20

同源策略与CORS跨域

PS:这篇文章是紧接着JSONP原理Ajax学习与理解写的,有些内容是承接了上两篇文章.
这篇文章只算是我的个人学习笔记,内容没有经过精心排版,也没有认真校对格式,一些错误请见谅.

用 form , a,img,link,script.都可以跨域发送请求
但是!
同源策略:只有 协议+端口+域名 一模一样才允许发 AJAX 请求.
例如我们向baidu.com发送Ajax一个请求
PdzFgg.png

PdzVDs.png
请求成功了,但是报了一个错
PdzmEq.png
加载失败了,
所以,请求发送出去了,但是拿不到响应!

同源策略

只有 协议+端口+域名 一模一样才允许发 AJAX 请求

一模一样一模一样一模一样一模一样一模一样一模一样一模一样一模一样

http://baidu.com 可以向 http://www.baidu.com 发 AJAX 请求吗 no
http://baidu.com:80 可以向 http://baidu.com:81 发 AJAX 请求吗 no
浏览器必须保证
只有 协议+端口+域名 一模一样才允许发 AJAX 请求

为什么要有同源策略?

为什么form表单提交没有跨域问题,但ajax提交有跨域问题? - 方应杭的回答 - 知乎

因为原页面用 form 提交到另一个域名之后,原页面的脚本无法获取新页面中的内容。所以浏览器认为这是安全的。而 AJAX 是可以读取响应内容的,因此浏览器不能允许你这样做。如果你细心的话你会发现,其实请求已经发送出去了,你只是拿不到响应而已。所以浏览器这个策略的本质是,一个域名的 JS ,在未经允许的情况下,不得读取另一个域名的内容。但浏览器并不阻止你向另一个域名发送请求。

简单地说就是使用form发送请求,就会刷新页面,所以原页面没有了,就认为是安全的.但是Ajax可以吧响应内容读取了.并且显示在本页面上.出现安全性问题

如果没有同源策略,那么任何网站都可以读取别人的支付宝余额等等

CORS 跨域

除了用jsonp之外,可以用CORS

下面我们用两个网站来模拟Ajax跨域并且解决跨域问题

先写前端的Ajax请求代码

let myButton = document.getElementById('myButton');
myButton.addEventListener("click",(e)=>{
    let request = new XMLHttpRequest();
    request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            console.log("请求和响应都完毕了");
            if ( request.status>=200&&request.status<=400){
                console.log('说明请求成功');
                let string = request.responseText;
                //把符合json语法的字符串转化为js对应的值
                let object2 = window.JSON.parse(string);
                console.log(object2)
            }else if(request.status>=400){
                console.log("响应失败");
            }
        } 
    }
    request.open('GET','http://jack.com:8002/xxx')//配置request.请求的路径为第二个网站的8002端口
    request.send();//发送请求
})

服务器端的代码

else if (path === '/xxx') {
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/xml;charset=utf-8')
    response.write(`
    {
      "note":{
        "from":"mataotao",
        "to":"ni",
      }
    }
    `)
    response.end()
  }

监听两个端口,然后用mataotao.com:8001的网站向jack.com:8002网站发起请求,这就算是跨域发送请求
Pw9l28.png

Pw9Q8f.png

点击点我后:
Pw98Kg.png
ajax请求因为跨域问题没有发送成功!

解决方法

一句代码:设置请求头:

//HTTP访问控制(CORS)允许来自http://mataotao.com:8001的请求,并给予相应
    response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
else if (path === '/xxx') {
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/xml;charset=utf-8')

    //HTTP访问控制(CORS)允许来自http://mataotao.com:8001的请求,并给予相应
    response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
    
    
    response.write(`
    {
      "note":{
        "from":"mataotao",
        "to":"ni",
      }
    }
    `)
    response.end()
  }

然后重启jack.com:8002的服务器,再重新请求一次

Pw9rMF.png
成功
CORS 可以告诉浏览器,我俩一家的,别阻止他

CORS的意思

突破同源策略 === 跨域

Cross-Origin Resource Sharing
跨域(源,站)资源共享

总结

CORS相对于JSONP,CORS可以发任意请求,而JSONP只能发送get请求

response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
这句话是跨域(突破同源策略)的核心,即允许别的网站(例如http://mataotao.com:8001)跨域向我发请求,并且允许响应

Ajax总结

什么是Ajax?

  1. 使用XMLHttpRequest发送请求
  2. 服务器返回json格式的字符串
  3. js解析json,并更新局部页面

面试手写Ajax

PwPu1f.png
就是这9行代码
一定要会!!!


风彻
1.5k 声望142 粉丝