js_XMLHTTPRequest与referrer

一、referrer

Referer其实应该是英文单词Referrer,不过编写标准的人拼错了,所以人们也就延用了referer。

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的。

比如在一个网页里面插入一个超链接,链接到其他的网页,那么当点击这个超链接从而链接到另外一个页面的时候,相当于浏览器向web服务器发送了一个 http请求,对于另外一个页面而言,这个referer就是上一个页面的URL,而对于从地址栏里面直接输入URL或者是刷新网页的方式,则referer = null,通过设置这个referer可以防止盗链的问题。

refere的作用

1.防盗链

只允许我本身的网站访问本身的图片服务器,假如域名是www.google.com,那么图片服务器每次取到Referer来判断一下域名是不是www.google.com,如果是就继续访问,不是就拦截。

将这个http请求发给服务器后,如果服务器要求必须是某个地址或者某几个地址才能访问,而你发送的referer不符合他的要求,就会拦截或者跳转到他要求的地址,然后再通过这个地址进行访问。

2.防止恶意请求

对于某些风险较高的文件类型,可使用Referer使得该类型文件只能来自我所指定的网站。

3.空Referer
有时,Referer内容为空,根据Referer的定义,它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源。

比如,直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含 Referer 字段的,因为这是一个“凭空产生”的 HTTP 请求,并不是从一个地方链接过去的。

Referer内容为空的情况有:

浏览器内直接输入URL
Windows桌面的超链接图标
浏览器内书签
第三方软件内容中的链接
盗链

盗链是指在自己的页面上展示一些并不在自己服务器上的一些内容, 获取别人的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。 一般被盗链的都是图片、 可执行文件、 音视频文件、压缩文件等资源。通过盗链的手段可以减轻自己服务器的负担

虽然Referer并不可靠,但用来防止图片盗链还是足够的,毕竟不是每个人都会修改客户端的配置。实现一般都是通过apache的配置文件,首先设置允许访问的地址。

防盗链的工作原理

通过Referer或者签名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以追踪到显示它的网页地址 一旦检测到来源不是本站,即进行阻止或者返回指定的页面

绕过图片防盗链

那么现在的很多网站是如何利用referer来进行防图片盗链的呢? 三种情况下允许引用图片:

本网站。

无referer信息的情况。(服务器认为是从浏览器直接访问的图片URL,所以这种情况下能正常访问)

授权的网址。

我们只能从情况2入手,通过设置referer为空进行绕过防盗链。

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

1.在HTML里设置meta

2.用、、、、

script src=‘/javascripts/test.js’ referrerpolicy=“no-referrer”>

二、iframe标签

标签用于在网页里面嵌入其他网页。 标签生成一个指定区域,在该区域中嵌入其他网页。它是一个容器元素,如果浏览器不支持,就会显示内部的子元素。 上面的代码在当前网页嵌入https://www.example.com,显示区域的宽度是100%,高度是500像素。如果当前浏览器不支持,则会显示一个链接,让用户点击。

浏览器普遍支持,所以内部的子元素可以不写。

sandbox 属性

嵌入的网页默认具有正常权限,比如执行脚本、提交表单、弹出窗口等。如果嵌入的网页是其他网站的页面,你不了解对方会执行什么操作,因此就存在安全风险。为了限制的风险,HTML 提供了sandbox属性,允许设置嵌入的网页的权限,等同于提供了一个隔离层,即“沙箱”。

sandbox可以当作布尔属性使用,表示打开所有限制。

sandbox属性可以设置具体的值,表示逐项打开限制。未设置某一项,就表示不具有该权限。

loading 属性

指定的网页会立即加载,有时这不是希望的行为。滚动进入视口以后再加载,这样会比较节省带宽。

loading属性可以触发网页的懒加载。该属性可以取以下三个值。

auto:浏览器的默认行为,与不使用loading属性效果相同。

lazy:的懒加载,即将滚动进入视口时开始加载。

eager:立即加载资源,无论在页面上的位置如何。

三、XMLHttpRequest

XMLHttpRequest (简称 xhr )是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数 据资源。

XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。

尽管名称如此,XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。它甚至支持 HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。

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”:字符串。

上面几种类型之中,text类型适合大多数情况,而且直接处理文本也比较方便。document类型适合返回 HTML / XML 文档的情况,这意味着,对于那些打开 CORS 的网站,可以直接用 Ajax 抓取网页,然后不用解析 HTML 字符串,直接对抓取回来的数据进行 DOM 操作。blob类型适合读取二进制数据,比如图片文件。

XMLHttpRequest.responseXML/JSON
XMLHttpRequest.responseXML属性返回从服务器接收到的 HTML 或 XML 文档对象,该属性为只读。如果本次请求没有成功,或者收到的数据不能被解析为 XML 或 HTML,该属性等于null。

该属性生效的前提是 HTTP 回应的Content-Type头信息等于text/xml或application/xml。这要求在发送请求前,XMLHttpRequest.responseType属性要设为document。如果 HTTP 回应的Content-Type头信息不等于text/xml和application/xml,但是想从responseXML拿到数据(即把数据按照 DOM 格式解析),那么需要手动调用XMLHttpRequest.overrideMimeType()方法,强制进行 XML 解析。

XMLHttpRequest.timeout,XMLHttpRequestEventTarget.ontimeout
XMLHttpRequest.timeout属性返回一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。如果该属性等于0,就表示没有时间限制。

XMLHttpRequestEventTarget.ontimeout属性用于设置一个监听函数,如果发生 timeout 事件,就会执行这个监听函数。

事件监听属性
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 的实例方法
XMLHttpRequest.open()
XMLHttpRequest.open()方法用于指定 HTTP 请求的参数,或者说初始化 XMLHttpRequest 实例对象。它一共可以接受五个参数。

void open(
string method,
string url,
optional boolean async,
optional string user,
optional string password
);
method:表示 HTTP 动词方法,比如GET、POST、PUT、DELETE、HEAD等。

url: 表示请求发送目标 URL。

async: 布尔值,表示请求是否为异步,默认为true。如果设为false,则send()方法只有等到收到服务器返回了结果,才会进行下一步操作。该参数可选。由于同步 AJAX 请求会造成浏览器失去响应,许多浏览器已经禁止在主线程使用,只允许 Worker 里面使用。所以,这个参数轻易不应该设为false。

user:表示用于认证的用户名,默认为空字符串。该参数可选。

password:表示用于认证的密码,默认为空字符串。该参数可选。

注意,如果对使用过open()方法的 AJAX 请求,再次使用这个方法,等同于调用abort(),即终止请求。

XMLHttpRequest.send()
XMLHttpRequest.send()方法用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只有一个 URL,没有数据体,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。

注意,所有 XMLHttpRequest 的监听事件,都必须在send()方法调用之前设定。

send方法的参数就是发送的数据。多种格式的数据,都可以作为它的参数。

void send();
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(String data);
void send(FormData data);
如果send()发送 DOM 对象,在发送之前,数据会先被串行化。如果发送二进制数据,最好是发送ArrayBufferView或Blob对象,这使得通过 Ajax 上传文件成为可能。

XMLHttpRequest.setRequestHeader()
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.overrideMimeType()
XMLHttpRequest.overrideMimeType()方法用来指定 MIME 类型,覆盖服务器返回的真正的 MIME 类型,从而让浏览器进行不一样的处理。举例来说,服务器返回的数据类型是text/xml,由于种种原因浏览器解析不成功报错,这时就拿不到数据了。为了拿到原始数据,我们可以把 MIME 类型改成text/plain,这样浏览器就不会去自动解析,从而我们就可以拿到原始文本了。

xhr.overrideMimeType(‘text/plain’)
注意,该方法必须在send()方法之前调用。

修改服务器返回的数据类型,不是正常情况下应该采取的方法。如果希望服务器返回指定的数据类型,可以用responseType属性告诉服务器,就像下面的例子。只有在服务器无法返回某种数据类型时,才使用overrideMimeType()方法。

XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.getAllResponseHeaders()方法返回一个字符串,表示服务器发来的所有 HTTP 头信息。格式为字符串,每个头信息之间使用CRLF分隔(回车+换行),如果没有收到服务器回应,该属性为null。如果发生网络错误,该属性为空字符串。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'foo.txt', true);
xhr.send();
​
xhr.onreadystatechange = function () {
  if (this.readyState === 4) {
    var headers = xhr.getAllResponseHeaders();
  }
}

上面代码用于获取服务器返回的所有头信息。它可能是下面这样的字符串。

date: Fri, 08 Dec 2017 21:04:30 GMT\r\n
content-encoding: gzip\r\n
x-content-type-options: nosniff\r\n
server: meinheld/0.6.1\r\n
x-frame-options: DENY\r\n
content-type: text/html; charset=utf-8\r\n
connection: keep-alive\r\n
strict-transport-security: max-age=63072000\r\n
vary: Cookie, Accept-Encoding\r\n
content-length: 6502\r\n
x-xss-protection: 1; mode=block\r\n

然后,对这个字符串进行处理。

var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};
​
arr.forEach(function (line) {
  var parts = line.split(': ');
  var header = parts.shift();
  var value = parts.join(': ');
  headerMap[header] = value;
});
​```
headerMap['content-length'] // "6502"
XMLHttpRequest.abort()
XMLHttpRequest.abort()方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState属性变为4,status属性变为0。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(function () {
  if (xhr) {
    xhr.abort();
    xhr = null;
  }
}, 5000);
上面代码在发出5秒之后,终止一个 AJAX 请求

XMLHttpRequest 实例的事件
readyStateChange 事件
readyState属性的值发生改变,就会触发 readyStateChange 事件。

我们可以通过onReadyStateChange属性,指定这个事件的监听函数,对不同状态进行不同处理。尤其是当状态变为4的时候,表示通信成功,这时回调函数就可以处理服务器传送回来的数据。

progress 事件
上传文件时,XMLHttpRequest 实例对象本身和实例的upload属性,都有一个progress事件,会不断返回上传的进度。

load 事件、error 事件、abort 事件
load 事件表示服务器传来的数据接收完毕,error 事件表示请求出错,abort 事件表示请求被中断(比如用户取消请求)。

timeout 事件
服务器超过指定时间还没有返回结果,就会触发 timeout 事件,具体的例子参见timeout属性一节。

# 四、ajax

Ajax:即异步 JavaScript 和XML。Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。而传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。
 

同步与异步的区别

同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,用户才可以使用页面。

异步提交:当用户发送请求时,当前页面还可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来 。

ajax的工作原理

客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上。
实现AJAX的基本步骤
要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:

创建XMLHttpRequest对象,即创建一个异步调用对象.
创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
设置响应HTTP请求状态变化的函数.
发送HTTP请求.
获取异步调用返回的数据.
使用JavaScript和DOM实现局部刷新.
创建完HTTP请求之后,应该就可以将HTTP请求发送给Web服务器了。然而,发送HTTP请求的目的是为了接收从服务器中返回的数据。从创建XMLHttpRequest对象开始,到发送数据、接收数据、XMLHttpRequest对象一共会经历以下5中状态。

未初始化状态。在创建完XMLHttpRequest对象时,该对象处于未初始化状态,此时XMLHttpRequest对象的readyState属性值为0。
初始化状态。在创建完XMLHttpRequest对象后使用open()方法创建了HTTP请求时,该对象处于初始化状态。此时XMLHttpRequest对象的readyState属性值为1。
发送数据状态。在初始化XMLHttpRequest对象后,使用send()方法发送数据时,该对象处于发送数据状态,此时XMLHttpRequest对象的readyState属性值为2。
接收数据状态。Web服务器接收完数据并进行处理完毕之后,向客户端传送返回的结果。此时,XMLHttpRequest对象处于接收数据状态,XMLHttpRequest对象的readyState属性值为3。
完成状态。XMLHttpRequest对象接收数据完毕后,进入完成状态,此时XMLHttpRequest对象的readyState属性值为4。此时接收完毕后的数据存入在客户端计算机的内存中,可以使用responseText属性或responseXml属性来获取数据。

  只有在XMLHttpRequest对象完成了以上5个步骤之后,才可以获取从服务器端返回的数据。因此,如果要获得从服务器端返回的数据,就必须要先判断XMLHttpRequest对象的状态。
 

设置获取服务器返回数据的语句
       如果XMLHttpRequest对象的readyState属性值等于4,表示异步调用过程完毕,就可以通过XMLHttpRequest对象的responseText属性或responseXml属性来获取数据。

       但是,异步调用过程完毕,并不代表异步调用成功了,如果要判断异步调用是否成功,还要判断XMLHttpRequest对象的status属性值,只有该属性值为200,才表示异步调用成功,因此,要获取服务器返回数据的语句,还必须要先判断XMLHttpRequest对象的status属性值是否等于200
注意:如果HTML文件不是在Web服务器上运行,而是在本地运行,则xmlHttpRequest.status的返回值为0。因此,如果该文件在本地运行,则应该加上xmlHttpRequest.status == 0的判断。
发送HTTP请求
       在经过以上几个步骤的设置之后,就可以将HTTP请求发送到Web服务器上去了。发送HTTP请求可以使用XMLHttpRequest对象的send()方法,其语法代码如下所示:

XMLHttpRequest.send(data);
       其中data是个可选参数,如果请求的数据不需要参数,即可以使用null来替代。data参数的格式与在URL中传递参数的格式类似
       只有在使用send()方法之后,XMLHttpRequest对象的readyState属性值才会开始改变,也才会激发readystatechange事件,并调用函数。

局部更新
       在通过Ajax的异步调用获得服务器端数据之后,可以使用JavaScript或DOM来将网页中的数据进行局部更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值