跨域限制原因:
为了防止攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
例子:
- 假如我们访问完银行的网站,浏览器保存返回的cookie。这里用nodeJs写一个http服务称为server1.js。
const http = require('http')//银行服务http.createServer(function(request,response){ console.log('request come',request.url) response.writeHead(200,{ // 'Access-Control-Allow-Origin':'http://localhost:8888' //这里如果放开就可以进行跨域 }) response.end('find the account have 123')}).listen(8887)console.log('server listening on')
- 然后不小心访问到黑客的嵌入了邪恶JavaScript脚本的网站。该网页嵌入了一个脚本会请求银行网站获取用户的银行余额。这里用nodeJs写一个http服务称为server2.js进行模拟,它会将服务器的test.html网页返回。
const http = require('http')const fs = require('fs')//黑客网站服务http.createServer(function(request,response){ console.log('request come',request.url) const html = fs.readFileSync('test.html','utf8') //读取html返回 response.writeHead(200,{ 'Content-Type':'text/html' }) response.end(html)}).listen(8888)console.log('server listening on')
- 以下是模拟盗取的黑客网页。
这时浏览器虽然仍会执行黑客网站上的脚本进行ajax请求银行服务查用户余额,但浏览器由于同源策略禁止跨域请求不会解析返回的结果,所以会在控制台提示以下信息。
- 当如果请求的方法不是get或者post的时候,或者使用自定义的请求头访问时,也会为了保护请求的服务器安全,浏览器也会进行拦截。
- 因此可以改变server2.js来使跨域允许。
const http = require('http')//银行服务http.createServer(function(request,response){ console.log('request come',request.url) response.writeHead(200,{ 'Access-Control-Allow-Origin':'*', //设置允许跨域的原始地址 'Access-Control-Allow-Headers':'X-Test-Cors', //设置允许跨域的请求头 'Access-Control-Allow-Methods':'PUT', //设置允许跨域的请求方法 'Access-Control-Max-Age':'1' //设置允许跨域时不用预请求的时间 }) response.end('find the account have 123')}).listen(8887)console.log('server listening on')
- 特别要注意的是:当跨域的请求不是get和post方式时,会多产生一个预请求在正式请求前。而Access-Control-Max-Age时间内就不会再发起预请求。