目录
Referer
Referrer-policy
设置referer
盗链
防盗链的工作原理
防盗链的三种方式
如何绕过图片防盗链
XMLHttpRequest
构造函数
XMLHttpRequest 的实例属性
XMLHttpRequest.readyState
XMLHttpRequest.onreadystatechange
XMLHttpRequest.response
XMLHttpRequest.responseType
XMLHttpRequest.status,XMLHttpRequest.statusText
XMLHttpRequest.responseText
XMLHttpRequest对象简单用法的完整例子
事件监听属性
方法
XMLHttpRequest.open(method,url,async,user, password)
XMLHttpRequest.send(string)
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.abort()
XMLHttpRequest 实例的事件
readyStateChange 事件
progress 事件
load 事件、error 事件、abort 事件
loadend 事件
timeout 事件
Referer
Referer请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用Referer(注:`正确英语拼写应该是referrer,由于早期HTTP规范的拼写错误,为了保持向后兼容就一直延续下来`)请求头识别访问来源,可能会以此统计分析、日志记录以及缓存优化等。
Referrer-policy
Referrer-policy作用就是为了控制请求头中referer的内容
- no-referrer : 整个referee首部会被移除,访问来源信息不随着请求一起发送。
- no-referrer-when-downgrade : 在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别的情况下,引用页面的地址会被发送(HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP).
- origin: 在任何情况下,仅发送文件的源作为引用地址。例如 https://example.com/page.html 会将 Example Domain 作为引用地址。
- origin-when-cross-origin: 对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。
- same-origin: 对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息。
- strict-origin: 在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。
- strict-origin-when-cross-origin: 对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。
- unsafe-url: 无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。(最不安全了)
设置referer
①在HTML中设置meta标签
<meta name="referrer" content="origin">
②用<a>、<area>、<img>、<iframe>、<script> 或者 <link> 元素上的 referrerpolicy 属性为其设置独立的请求策略。
如:
<script src='/javascripts/test.js' referrerpolicy="no-referrer"></script>
【可以理解成局部政策】
盗链
盗链就是在自己的页面里展示别人服务器里的一些东西
例如
<body>
<img src=" 网络源照片.jpg">
</body>
发现没偷到照片,这就是有防盗链的措施
防盗链的工作原理
通过Referer或者签名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以追踪到显示它的网页地址 一旦检测到来源不是本站,即进行阻止或者返回指定的页面
防盗链的三种方式
1. 时间戳防盗链
在url链接中加入时间戳信息,来防止盗链。当盗链者没有及时更新url链接时,便会无法访问。这是一种常规方式,假如盗链者比较勤奋,经常更新url链接,则时间戳的方法会失效。
2. 中心鉴权
中心鉴权等于在源站加一层验证,对防盗链有效,但是用户请求时间会增加,影响体验,最好搭配CDN使用,先让终端用户的请求通过CDN节点,再通过鉴权服务器鉴权,降低请求时间。
3. Referer防盗链
Referer是http一个标记,它会告诉服务器该网页是从哪里来的,通过设置Referer黑白名单来防止被盗链。
如何绕过图片防盗链
那么现在的很多网站是如何利用referer来进行防图片盗链的呢?
三种情况下允许引用图片:
1. 照片是本网站的。
2. 请求头里没有referer信息的情况。(服务器认为是从浏览器直接访问的图片URL,所以这种情况下能正常访问)
3. 被你要盗链的服务器授权的网址。
因此我们只能从情况2入手,通过设置referer为空进行绕过防盗链。
具体操作需要学习JS,水平有限暂时不复现了
XMLHttpRequest
【哪里用得上?】
本来是在浏览器那输入网址然后浏览器向服务器发出http请求,后面IE更新引入新功能,可以用JS向服务器发起http请求,简单来说,页面可以自己悄悄更新数据不影响你。js向服务器发起http请求的过程也叫做AJAX(Asynchronous JavaScript and XML)(阿贾克斯)
XML格式已经过时,但这个名字沿用了下来
AJAX包括以下几个步骤
- 创建 XMLHttpRequest 实例【这个就是下边要讲的了】
- 发出 HTTP 请求
- 接收服务器传回的数据
- 更新网页数据
XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这⭐允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。
尽管名称如此,XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。它甚至支持 HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。
构造函数
XMLHttpRequest()
该构造函数用于初始化一个 XMLHttpRequest 实例对象。在调用任何其他方法之前,必须先调用该构造函数,或通过其他方式,得到一个实例对象。
创建 XMLHttpRequest 对象的语法:
var 实例对象名字 = new XMLHttpRequest();
XMLHttpRequest 的实例属性
XMLHttpRequest.readyState
`XMLHttpRequest.readyState`返回一个整数,表示实例对象的当前状态。该属性只读。它可能返回以下值。
- 0,表示 XMLHttpRequest 实例已经生成,但是实例的`open()`方法还没有被调用。
- 1,表示`open()`方法已经调用,但是实例的`send()`方法还没有调用,仍然可以使用实例的`setRequestHeader()`方法,设定 HTTP 请求的头信息。
- 2,表示实例的`send()`方法已经调用,并且服务器返回的头信息和状态码已经收到。
- 3,表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的`responseType`属性等于`text`或者空字符串,`responseText`属性就会包含已经收到的部分信息。
- 4,表示服务器返回的数据已经完全接收,或者本次接收已经失败。
通信过程中,每当实例对象发生状态变化,它的`readyState`属性的值就会改变。这个值每一次变化,都会触发`readyStateChange`事件。
XMLHttpRequest.onreadystatechange
XMLHttpRequest.onreadystatechange属性指向一个监听函数。readystatechange事件发生时(实例的`readyState`属性变化),就会执行这个属性。
另外,如果使用实例的`abort()`方法,终止 XMLHttpRequest 请求,也会造成`readyState`属性变化,导致调用`XMLHttpRequest.onreadystatechange`属性。
XMLHttpRequest.response
`XMLHttpRequest.response`属性表示服务器返回的数据体(即 HTTP 回应的 body 部分)。它可能是任何数据类型,比如字符串、对象、二进制对象等等,具体的类型由`XMLHttpRequest.responseType`属性决定。该属性只读。
如果本次请求没有成功或者数据不完整,该属性等于`null`。但是,如果`responseType`属性等于`text`或空字符串,在请求没有结束之前(`readyState`等于3的阶段),`response`属性包含服务器已经返回的部分数据。
XMLHttpRequest.responseType
`XMLHttpRequest.responseType`属性是一个字符串,表示服务器返回数据的类型。这个属性是可写的,可以在调用`open()`方法之后、调用`send()`方法之前,设置这个属性的值,告诉浏览器如何解读返回的数据。如果`responseType`设为空字符串,就等同于默认值`text`。
`XMLHttpRequest.responseType`属性可以等于以下值。
- ""(空字符串):等同于`text`,表示服务器返回文本数据。
- "arraybuffer":ArrayBuffer 对象,表示服务器返回二进制数组。
- "blob":Blob 对象,表示服务器返回二进制对象。
- "document":Document 对象,表示服务器返回一个文档对象。
- "json":JSON 对象。
- "text":字符串。
XMLHttpRequest.status,XMLHttpRequest.statusText
`XMLHttpRequest.status`属性返回一个整数,表示服务器回应的 HTTP 状态码。一般来说,如果通信成功的话,这个状态码是200;如果服务器没有返回状态码,那么这个属性默认是200。请求发出之前,该属性为`0`。该属性只读。
- 200, OK,访问正常
- 301, Moved Permanently,永久移动
- 302, Moved temporarily,暂时移动
- 304, Not Modified,未修改
- 307, Temporary Redirect,暂时重定向
- 401, Unauthorized,未授权
- 403, Forbidden,禁止访问
- 404, Not Found,未发现指定网址
- 500, Internal Server Error,服务器发生错误
基本上,只有2xx和304的状态码,表示服务器返回是正常状态。
XMLHttpRequest.responseText
`XMLHttpRequest.responseText`属性返回从服务器接收到的字符串,该属性为只读。只有 HTTP 请求完成接收以后,该属性才会包含完整的数据。
XMLHttpRequest对象简单用法的完整例子
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
// 通信成功时,状态值为4
if (xhr.readyState === 4){
if (xhr.status === 200){
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
xhr.open('GET', '/endpoint', true);
xhr.send(null);
事件监听属性
XMLHttpRequest 对象可以对以下事件指定监听函数。
- XMLHttpRequest.onloadstart:loadstart 事件(HTTP 请求发出)的监听函数
- XMLHttpRequest.onprogress:progress事件(正在发送和加载数据)的监听函数
- XMLHttpRequest.onabort:abort 事件(请求中止,比如用户调用了`abort()`方法)的监听函数
- XMLHttpRequest.onerror:error 事件(请求失败)的监听函数
- XMLHttpRequest.onload:load 事件(请求成功完成)的监听函数
- XMLHttpRequest.ontimeout:timeout 事件(用户指定的时限超过了,请求还未完成)的监听函数
- XMLHttpRequest.onloadend:loadend 事件(请求完成,不管成功或失败)的监听函数
方法
XMLHttpRequest.open(method,url,async,user, password)
初始化一个请求。
method:请求的类型;GET 或 POST
url:文件在服务器上的位置
async:true(异步)或 false(同步)
user&password:string可选填参数
XMLHttpRequest.send(string)
将请求发送到服务器。如果请求是异步的(默认),那么该方法将在请求发送后立即返回。
string:仅用于 POST 请求
如果对象open过了再open一遍等于abort(),终止请求
GET 请求
xmlhttp.open("GET","demo_get.asp",true);
xmlhttp.send();
在上面的例子中,您可能得到的是缓存的结果。
为了避免这种情况,请向 URL 添加一个唯一的 ID:
【后面加个随机数即可】
xmlhttp.open("GET","demo_get.asp?t=" + Math.random(),true);
xmlhttp.send();
POST 请求
xmlhttp.open("POST","demo_post.asp",true);
xmlhttp.send();
【注:所有 XMLHttpRequest 的监听事件,都必须在send()方法调用之前设定】
XMLHttpRequest.setRequestHeader()
此方法用于设置浏览器发送的HTTP请求头的信息,【只能在open()send()两个方法之间调用】如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length',,JSON.stringify(data).length);
xhr.send(JSON.stringify(data));
上面代码首先设置头信息Content-Type,表示发送 JSON 格式的数据;然后设置Content-Length,表示数据长度;最后发送 JSON 数据。
XMLHttpRequest.abort()
`XMLHttpRequest.abort()`方法用来终止已经发出的 HTTP 请求。调用这个方法以后,`readyState`属性变为`4`,`status`属性变为`0`。
XMLHttpRequest 实例的事件
readyStateChange 事件
`readyState`属性的值发生改变,就会触发 readyStateChange 事件。
我们可以通过`onReadyStateChange`属性,指定这个事件的监听函数,对不同状态进行不同处理。尤其是当状态变为`4`的时候,表示通信成功,这时回调函数就可以处理服务器传送回来的数据。
progress 事件
上传文件时,XMLHttpRequest 实例对象本身和实例的`upload`属性,都有一个`progress`事件,会不断返回上传的进度
load 事件、error 事件、abort 事件
load 事件表示服务器传来的数据接收完毕,error 事件表示请求出错,abort 事件表示请求被中断(比如用户取消请求)。
loadend 事件
`abort`、`load`和`error`这三个事件,会伴随一个`loadend`事件,表示请求结束,但不知道其是否成功
timeout 事件
服务器超过指定时间还没有返回结果,就会触发 timeout 事件,具体的例子参见`timeout`属性一节。
【注意,AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错(详见《同源政策》和《CORS 通信》两章)。】