概念:
CORS(跨域资源共享)是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不一样源服务器上的指定的资源。
发起请求的域与请求指向的域所在的资源不同,就造成了跨域。
域资源经常包括 协议、域名(IP)、端口号,若均相同,就是同域,若一个不相同,则是跨域。
跨域请求的安全问题
标签<a> <form> <img> <script> <ifram> <link> <video> <audio>,都含有src属性,可以发起请求,也就可能造成跨域。
浏览器之因此要对跨域请求做出限制,是出于安全方面的考虑,由于跨域请求可能会形成CSRF(Cross Site Request Forgery)攻击。
用户在A网站登陆后,攻击者诱导用户访问一个攻击页面B,此时得到了用户的信息,好比cookie,session、token等,此时A网站已信任用户,
以用户身份在攻击页面B,伪造用户操做的请求,攻击A网站。
模拟跨域
下面Demo模拟跨域。
新建两个Js,man.js与cross.js,分别为端口号 8888与8887 服务。
启动好后, 使用 http://127.0.0.1:8888访问,即出现跨域错误。
整个思想是: 请求8888端口服务时,会获取html文档,此文档会当即访问 8887端口服务。
main.js 8888端口
const http = require('http'); const fs = require('fs'); http.createServer((request, response) => { const html = fs.readFileSync('allowOrigin.html', 'utf8'); if (request.url === '/') { response.writeHead(200, { 'Content-Type': 'text/html' }); response.end(html); } }).listen(8888);
cross.js 8887 端口javascript
const http= require('http'); const fs = require('fs'); http.createServer( (request,response)=>{ console.log('服务器已经接受到了数据') response.writeHead(200,{ 'Content-Type':'text/html', 'Access-Control-Allow-Origin':'http://127.0.0.1' }); response.end('123'); }).listen(8887);
allowOrigin.html
<!DOCTYPE html> <html lang="en"> <body> <div>Access-Control-Allow-Origin</div> <script type="text/javascript"> let xhr=new XMLHttpRequest(); xhr.open('Get','http://127.0.0.1:8887'); xhr.send(); </script> </body> </html>
运行结果: 此时,浏览器会出现以下请求错误。html
其实, 浏览器发起请求时,并不知道请求是否跨域,所以仍然会发给服务器。
服务器接受请求后,才会对此做出判断,数据也返回了,只是被浏览器给拦截了。
所以,"服务器已经接受到了数据"这句话仍是会被 console 出来。
为了解决这个跨域问题,须要将croos.js容许跨域的范围改为 'Access-Control-Allow-Origin':'http://127.0.0.1:8888' 。
与跨域相关的响应首部还有:
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentiials