浏览器SOP
Posted 行似深夜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器SOP相关的知识,希望对你有一定的参考价值。
同源策略(SOP)
同源策略(Same origin policy)是一个重要的安全策略,它用于限制一个源的资源如何与另一个源的资源进行交互。
通过fetch跨域请求
让index文件运行在client服务器上,然后用fetch请求server服务器。
index.html
<script> fetch("http://127.0.0.1:3001/script"); </script>
client.js
const http = require("http"); const fs = require("fs"); const exec = require("child_process"); http.createServer((req, res) => const url = req.url; if (url === "/") fs.createReadStream("index.html").pipe(res); ).listen(3000); exec("start http://127.0.0.1:3000/");
server.js
const http = require("http"); http.createServer((req, res) => const url = req.url; if (url === "/script") console.log( "\\n>>>消息\\n\\n我收到了来自“http://127.0.0.1:3000/”的“http://127.0.0.1:3001/script”请求\\n\\n<<<消息", ); ).listen(3001);
用node启动client和server。
查看network,status是待处理;再看看node日志,已经接收到跨域请求了。
然后再让server服务器响应本次请求。
if (url === "/script") console.log( "\\n>>>消息\\n\\n我收到了来自“http://127.0.0.1:3000/”的“http://127.0.0.1:3001/script”请求\\n\\n<<<消息", ); return res.end("/script");
重新启动server服务器,刷新页面,发现控制台报错了。
这个就是CORS错误,原因是响应头没有配置“Access-Control-Allow-Origin”标头,未公开的资源说明不太安全,所以屏蔽掉了响应体。
查看请求头,发现有一个Origin标头,这是浏览器告诉服务器本次请求来自于哪里。
尽管浏览器SOP阻止跨域行为,但是如果证明跨域资源足够安全,就允许该资源在本地执行,所以有了CORS。
跨域资源共享策略(CORS)
跨域资源共享策略(Cross-origin Resource Sharing)是浏览器端和服务器端的一种约定,通过约定来表示跨域资源的安全性;这种约定由请求头和响应头来完成。
服务器对于安全性比较低或者公开的资源,例如图片、公共js库等,允许任意源访问。
在报文发送前,添加Access-Control-Allow-Origin标头。
res.writeHead(200, "Access-Control-Allow-Origin": "*", );
重新启动server服务器,刷新页面,这个时候跨域请求就成功了。
CORS 策略将跨域请求分为两类:简单请求和非简单请求;我们上面的情况属于简单请求。
非简单请求在发送前,会先发送一次预检请求(OPTIONS),服务器同意以后开始发送实际请求。
根据MDN的文档定义,请求方法为:GET、POST、HEAD,请求头Content-Type为:text/plain、multipart/form-data、application/x-www-form-urlencoded的就属于简单请求。
下面发送一个非简单请求。
在index.js中添加自定义标头:
<script> fetch("http://127.0.0.1:3001/script", headers: "test-1": "a", "test-2": "b", , ); </script>
在server.js中添加三个标头:
"Access-Control-Allow-Headers": "test-1,test-3", "Access-Control-Allow-Methods": "GET,PUT,DELETE", "Access-Control-Max-Age": 10,
重新启动server服务器,刷新页面,发现有报错。
可以看到,fetch请求使用了服务器不支持的标头,所以预检请求没通过。test-3改成test-2再试一次,预检通过。
Access-Control-Max-Age表示本次预检请求的时效性,单位是s,在这个时间内再次发起相同的请求,不需要再次提交预检请求;10秒内连续刷新页面试试。
略
以上是关于浏览器SOP的主要内容,如果未能解决你的问题,请参考以下文章