概念
Referer是HTTP请求头信息中的一个字段,它用于表示当前请求是从哪个URL页面跳转过来的。一般情况下,浏览器会自动发送Referer字段给服务器端,服务器端可以通过该字段来进行一些操作,比如判断当前请求是否合法、实现防盗链等功能。同时,由于历史原因和安全问题,Referer也存在一些限制和漏洞,需要我们在使用时进行注意和规避。
Referrer-policy(可以一定程度上防御CSRF攻击)
Referrer-policy的作用就是为了控制请求头部中的referer的内容
包含了以下信息:
- no-referer:整个referer首部会被移除,访问来源信息不随着请求一起发送。
- no-referer-when-downgrade:在没有指定任何策略的情况下用户代理的默认行为。在同安全等级的情况下,发送文件的源为引用地址(HTTPS->HTTPS);在降级的情况下不会发送此首部(HTTPS->HTTP)
- origin:在任何情况下,仅发送文件的源作为引用地址,
- orgin-when-cross-origin:对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅仅发送文件的源
- same-orgin:对于同源的请求会发送引用地址,但是对于非的同源请求则不发送引用地址信息。
- strict-origin:在同等安全级别的情况下,发送文件的源作为引用地址(HTPPS->HTTPS),但是在降级的情况下不会发送(HTTPS->HTTP)
- strict-origin-cross-origin,对于同源的请求,会发送完整的URL作为引用地址;在同安全等级的情况下,发送文件的源为引用地址(HTTPS->HTTPS);在降级的情况下不会发送此首部(HTTPS->HTTP)
- unsafe:无论是同源请求还是非同源请求,都发送完整的URL(移除参数信息后)作为引用地址。(最不安全了)
同源
那些网址符合同源的要求:协议相同、host相同、端口相同
例如:
http://www.baidu.com https://www.baidu.com-<这两个非同源(因为协议不同)
如果嵌入的网页是其他网站的网页,你不了解对方会执行什么操作,因此就存在安全风险。为了限制<iframe>的风险,HTML提供了sandbox属性,允许设置嵌入的网页的权限,等同于提供了一个隔离层,即“沙箱“
iframe
概念:
iframe标签是HTML中的一个内置标签,它允许我们在一个网页中嵌入另外一个网页。通过使用iframe标签,我们可以将一个页面的某个部分独立出来,形成一个新的窗口,从而实现一些有趣的功能和效果。
具体来说,通过使用iframe标签,我们可以:
- 在一个网页中嵌入其他网页,实现页面嵌套和组合;
- 实现异步加载某些内容,比如广告、推荐内容等;
- 实现一些特殊的展示效果,比如浮动窗口、弹出框等;
- 实现网页和服务器端的交互,比如提交表单、上传文件等。
不过需要注意的是,由于iframe标签存在一些安全问题,比如跨域攻击等问题,因此在使用时需要进行一些安全措施,保证网站的安全性。
sandbox(沙箱):
sandbox是Web开发中的一个重要安全机制,它允许我们在一个沙盒环境中执行不信任的代码,从而提高应用程序的安全性,它可以通过限制某些权限和行为,增强应用程序的安全性,避免安全漏洞和攻击风险。具体来说,sandbox可以通过以下方式增强Web应用程序的安全性:
限制JavaScript的权限
防止跨站点脚本攻击
防止点击劫持
设置嵌入的网页的权限:
对嵌入网页可以设置的权限:
* allow-forms:允许提交表单。
* allow-modals:允许提示框,即允许执行window.alert()等会产生弹出提示框的 JavaScript 方法。
* allow-p
opups:允许嵌入的网页使用window.open()方法弹出窗口。
* allow-popups-to-escape-sandbox:允许弹出窗口不受沙箱的限制。
* allow-orientation-lock:允许嵌入的网页用脚本锁定屏幕的方向,即横屏或竖屏。
* allow-pointer-lock:允许嵌入的网页使用 Pointer Lock API,锁定鼠标的移动。
* allow-presentation:允许嵌入的网页使用 Presentation API。
* allow-same-origin:不打开该项限制,将使得所有加载的网页都视为跨域。
* allow-scripts:允许嵌入的网页运行脚本(但不创建弹出窗口)。
* allow-storage-access-by-user-activation:sandbox属性同时设置了这个值和allow-same-origin的情况下,允许<iframe>嵌入的第三方网页通过用户发起document.requestStorageAccess()请求,经由 Storage Access API 访问父窗口的 Cookie。
* allow-top-navigation:允许嵌入的网页对顶级窗口进行导航。
* allow-top-navigation-by-user-activation:允许嵌入的网页对顶级窗口进行导航,但必须由用户激活。
* allow-downloads-without-user-activation:允许在没有用户激活的情况下,嵌入的网页启动下载。
注意,不要同时设置allow-scripts和allow-same-origin属性,这将使得嵌入的网页可以改变或删除sandbox属性。
cookie的原理:
用户第一次登录时,浏览器自动记录账号和密码等信息;账号明文,密码使用密文机密;cookie保存用户信息完成后,将这些信息发送给客户端,客户端将这些信息保存在本地;
如何设置Referrer?
方法一:
例如:
然后在浏览器测试会发现确实没有了referrer:
注意:如果使用链接的方式将该网页显示出来则referrer还是会照常存在的
例:
b网页将a网页通过链接的方式引入
当在浏览器中通过点击链接访问a网页时:
方法二:
也可以使用js中的referrerpolicy策略来设置no-referrer
例:
在浏览器中查看:
盗链
盗链是指自己的页面展示的但是实际并不在自己服务器的一些内容,获取别人的资源地址,绕过比人的资源展示页面,直接在自己的页面上向最终用用户提供此内容,一般被盗链的都是图片、可执行文件、音频文件、压缩文件等资源。通过盗链的手段可以减轻自己的服务器的负担
盗链的工作原理
通过referer或者签名,网站可以检测到目标页面访问的来源网页,如果是资源文件,则可以追踪显示到它网页地址,一旦检测到来源不是本站点,即进行阻止或者返回指定的页面
三种情况下可以引用图片:
- 本网站
- 无referer信息的情况下(即服务器认为从浏览器直接访问图片的图片的URL,所以这种情况下可以正常访问)
- 授权的网址
XMLHTTPRequest
AJAX(Asynchronous JavaScript and XML)
原理:通过JavaScript的异步通信,从服务器获取XML文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX这个词就成为了JavaScript脚本发起HTTP通信的代名词,也就是说,只要用脚本发起通信,就可以叫做AJAX通信
具体来说,AJAX包括以下几个步骤:
- 创建XMLHttpRequest实例
- 发出HTTP请求
- 接收服务器传回的数据
- 更新网页数据
- AJAX最关键的功能:页面无刷新
- AJAX通过原生的XMLHTTPRquest对象发出的HTTP请求,得到服务器返回的数据后,再进行处理。现在服务器返回的都是JSON格式的数据,XML格式已经过时了。
- XMLHTTPRequest对象是AJAX的主要接口,用于浏览器与服务器之间的通信。
- XMLHttpRequest本身是一个构造函数,可以使用new命令生成实例,并且它没有任何的参数。
- 一旦拿到服务器返回的数据,AJAX 不会刷新整个网页,而是只更新网页里面的相关部分,从而不打断用户正在做的事情。
例如:
var xhr new XMLHttpRequest();
注意:AJAX只能向同源网址(协议、域名、端口都相同)发出HTTP请求,如果发出跨域请求,就会报错
XMLHttpRequest的实例属性
XMLHttpRequest.readyState
这个属性会返回一个整数,表示实例对象的当前状态。该属性为只读
返回值类型:
- 0:表示XMLHttpRequest实例已经生成,但是实例的open()方法还没有被调用
- 1:表示open()方法已经调用,但是实例的send()方法还是没有调用,仍然可以使用实例的
setRequestHeader()
方法,设定 HTTP 请求的头信息。 - 3:表示正在接受服务器传来的数据体(body部分)。这时,如果实例的
responseType
属性等于text
或者空字符串,responseText
属性就会包含已经收到的部分信息。 - 4:表示服务器返回的数据已经完全接受,或者本次接受已经失败
通信过程中,每当实例对象发生状态变化,它的
readyState
属性的值就会改变。这个值每一次变化,都会触发
readyStateChange
事件。
XMLHttpRequest.onreadystatechange
这个属性指向一个监听函数。
readstatecahnge事件发生时(实例的readystate属性变化),就会执行这个属性
另外,如果使用实例的
abort()
方法,终止 XMLHttpRequest 请求,也会造成
readyState
属性变化,导致调用
XMLHttpRequest.onreadystatechange
属性。
XMLHttpRequest.response
这个属性表示服务器返回的数据体(即回应的body部分),它可能是任意的数据类型,具体的类型由XMLHttpRequest.responeType属性决定。该属性为只读
如果本次请求没有成功或者数据不完整,该属性等于null。但是如果responeType属性等于text或者字符串,在请求没有结束之前(readyState等于3的阶段),response属性包含服务器已经返回的部分数据
XMLHttpRequest.responeType
这个属性是一个字符串,表示服务器返回数据的类型。这个属性是可读可写的,可以是在调用open()方法之后、调用send()之前,设置这个属性的值,告诉浏览器如何解读返回的数据。如果responeType设为空字符串,就等于默认值text。
返回值的类型包括:
- "":等同于text,表示服务器返回文本数据
- "arratbufferr":表示服务器返回二进制数组
- "blob":表示服务器返回二进制对象
- "document":表示服务器返回一个文档对象
- "json":JSON对象
- "text":字符串
text类型适合大多数情况,直接处理文本也比较方便
document类型适合返回HTML/XML文档的情况,这意味着,对于那些打开CORS的网站,可以直接yongAJAX抓取网页,然后不用接卸HTML字符串,直接抓取回来的数据进行DOMC操作
Blob类型适合读取二进制数据,比如图片文件
如果将这个属性设为**
ArrayBuffer
**,就可以按照数组的方式处理二进制数据。
如果将这个属性设为**
json
**,浏览器就会自动对返回数据调用
JSON.parse()
方法。也就是说,从
xhr.response
属性(注意,不是
xhr.responseText
属性)得到的不是文本,而是一个 JSON 对象。
XMLHttpRequest.responeText
这个属性返回从服务器接受到的字符串,该属性为只读。
只有HTTP请求接受完成以后,该属性才会包含完整的数据
XMLHttpRequwst.responeXML
这个属性返回从服务器接受到的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 解析。该属性得到的数据,是直接解析后的文档 DOM 树。
XMLHttpRequwst.responeURL
该属性是字符串,表示发送数据的服务器的网址
注意:这个属性的值与open()方法指定的请求网址不一定相同。如果服务器端发生跳转,这个属性返回最后实际返回数据的网址,另外原始URL包括锚点,该属性会把锚点剥离
XMLHttpRequest.status
这个属性返回一个整数,表示服务器回应的HTP状态码。请求发送之前状态码为0,发送成功为200,如果没有返回码默认也为200
常见的返回码:
- 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,服务器发生错误
XMLHttpRequests.tatusText
这个属性返回一个字符串,表示服务器发送的状态提示。不同status属性,该属性包含整个状态信息,比如"OK"和"Not Found"。该属性为只读
在请求发送之前(即调用open()方法之前),该属性的值为空字符串;如果服务器没有返回状态提示,该属性的值默认为“OK”。
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 事件(请求完成,不管成功或失败)的监听函数
progress事件的监听函数有一个事件对象参数,该对象有三个属性:
- load属性返回已经传输的数据量,
- total属性返回总的数据量,
- legthComputable属性返回一个布尔值,表示加载的进度是否可以计算
所有的这些监听函数中,只有progress事件的监听函数有参数,其他函数都没有参数
注意:如果发生网络错误(比如服务器无法连接),onerror时间无法获取错误信息。也就是说,可能没有错误对象,所以这样只能显示报错的提示
XMLHttpRequest.withCredentials
这个属性是一个布尔值,表示跨域请求时,用户信息(比如Cookie和认证的HTTP头信息)是否会包含在其中,默认为false。
如果需要跨域AJAX请求发送Cookie,需要withCredentials属性设置为true。(同源的请求不需要设置这个属性)
为了让这个属性生效,服务器必须显式返回Access-Control-Allow-Credentials这个头信息
withCredentials
属性打开的话,跨域请求不仅会发送 Cookie,还会设置远程主机指定的 Cookie。
**注意,脚本总是遵守同源政策,无法从
document.cookie
或者 HTTP 回应的头信息之中,读取跨域的 Cookie,
withCredentials
属性不影响这一点**
XMLHttpRequest.upload
XMLHttpRequest不仅可哟发送请求,还可以发送文件,这就是AJAX文件上传。
发送文件后,通过这个属性可以得到一个对象,通过观察这个对象,可以得知上传的进展。主要方法就是监听和这个对象的各种事件loadstart,loadend,load,abort,error,progress,timeout
XMLHttpRequest的实例方法
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()方法只有等到收到服务器返回来结果,才会进行洗衣不操作。该参数可选
- user:表示用于认证的用户名,默认为空字符串。该参数可选。
- password:表示用于认证的密码,默认为空字符串。该参数可选
注意:如果对使用过open()方法的AJAX请求,再使用这个方法,等同于调用abort(),即终止请求
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()
这个方法用于设置浏览器发送的HTTP请求的头信息。
该方法接受两个参数。第一个参数是字符串,表示信息的字段名,第二个参数是字段值。
该方法必须在open()之后、send()之前调用,如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。
XMLHttpRequest.overrideMimeType()
这个方法用来指定MIME类型,覆盖服务器返回的真正的MIME类型,从而让浏览器进行不一样的处理。
举例来说,服务器返回的数据类型是text/xml,由于种种原因浏览器解析不成功报错,这时就拿不到数据了。为了拿到原始数据,我们可以把MIME类型改为text/plain,这样浏览器就不会去自动解析,从而我们就可以拿到原始文本了。
例如:
xhr.oberrideMimeType('text/plain')
注意:该方法必须在send()方法之前调用
修改服务器返回的类型,不是正常情况下应该采取的方法。如果希望服务器返回指定的数据类型们可以适应responeType属性告诉服务器。只有在服务器无法返回某种数据类型时,才使用overrideMimeType()方法。
XMLHttpRequest.getResponeHeader()
这个方法返回HTTP头信息指定字段的值。这个方法的参数不区分大小写
如果还没有收到服务器回应挥着指定字段不存在,返回null。
如果有多个字段同名,他们的值会被连接为一个字符串,每个字段之间使用(逗号加空格)分割。
XMLHttpRequest.getAllResponseHeader
这个方法返回一个字符串,表示是服务器发来的所有HTTP头信息。格式为字符串,每个头信息之间使用CRLF分割(回车加换行)
如果没有收到服务器回应,该属性为null。
如果发生网络错误,该属性为空字符串。
XMLHttpRequest.abort()
这个方法用来终止已经发出的HTTP请求。调用这个方法以后,readstate属性变为4,status属性变为0。
XMLHttpRequest的实例事件
readyStateChange事件
readyState
属性的值发生改变,就会触发 readyStateChange 事件。
我们可以通过
onReadyStateChange
属性,指定这个事件的监听函数,对不同状态进行不同处理。尤其是当状态变为
4
的时候,表示通信成功,这时回调函数就可以处理服务器传送回来的数据。progress事件
上传文件时,XMLHttpRequest 实例对象本身和实例的
upload
属性,都有一个
progress
事件,会不断返回上传的进度。
load事件
oad 事件表示服务器传来的数据接收完毕
erro事件
error 事件表示请求出错
abort事件
load 事件表示服务器传来的数据接收完毕,error 事件表示请求出错,
loadend事件
abort
、
load
和
error
这三个事件,会伴随一个
loadend
事件,表示请求结束,但不知道其是否成功。
timeout事件
服务器超过指定时间还没有返回结果,就会触发 timeout 事件,具体的例子参见
timeout
属性一节。
版权归原作者 未知百分百 所有, 如有侵权,请联系我们删除。