浏览器跨域问题

跨域限制原因:

为了防止攻击者盗用了你的身份,以你的名义发送恶意请求。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')
  • 以下是模拟盗取的黑客网页。
<!--嵌入偷偷请求银行服务网站的脚本-->
<html>
    <script>
    alert("look at your bank accout secretly")
    var xhr = new XMLHttpRequest()
    xhr.open('GET','http://127.0.0.1:8887')
    xhr.send()
    console.log(xhr)
    </script>
</html>
  • 这时浏览器虽然仍会执行黑客网站上的脚本进行ajax请求银行服务查用户余额,但浏览器由于同源策略禁止跨域请求不会解析返回的结果,所以会在控制台提示以下信息。

  • 当如果请求的方法不是get或者post的时候,或者使用自定义的请求头访问时,也会为了保护请求的服务器安全,浏览器也会进行拦截。

<!--嵌入偷偷请求银行服务网站的脚本-->
<html>
    <script>
    alert("look at your bank accout secretly")
    fetch('http://127.0.0.1:8887',{
        method:'PUT ',
        headers:{
            'X-Test-Cors':'123'
        }
    })
    </script>
</html>
  • 因此可以改变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时间内就不会再发起预请求。
posted @ 2018-08-23 00:57  21Java  阅读(156)  评论(0编辑  收藏  举报