目录:
  • 什么是Ajax跨域?
  • 什么是同源策略?
  • 怎么解决跨域?
    • JSONP
    • CORS

什么是Ajax跨域?

同源策略是跨域问题产生的根本原因。并且跨域是浏览器行为,也就是说服务器发送了请求,客户端也接收到了只是浏览器拒绝接收服务器传回的数据。

什么是同源策略?

同源策略是指在Web浏览器中,允许某个网页脚本访问另一个网页的数据,但前提是这两个网页必须有相同的协议、域名和端口,一旦两个网站满足上述条件,这两个网站就被认定为具有相同来源。

怎样解决跨域?

本文只探究两个方法:JSONP和CORS。

JSONP:

JSONP解决跨域,主要因为<script>标签具有跨域能力。因此只是“绕过”了跨域,并没有根本解决问题。

JSONP跨域实现:

function cb(result) {
    console.log(result)
}

btn.onclick = function () {
    let sc = document.createElement("script");
    sc.src = "http://suggest.taobao.com/sug?code=utf-8&q=电脑&callback=cb"
    document.body.appendChild(sc)
}

实现原理主要是创建了script标签,改变src属性值。并且请求方式必须是GET,必须使用和后端相同的回调函数名获取后端数据。

JSONP跨域优缺点:

优点:

  • 兼容性好

缺点:

  • 只能使用GET请求
  • 后端必须拥有回调函数且函数名和前端相同
  • 错误处理机制并不完善

CORS:

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS解决跨域分为简单请求和复杂请求。

区分CORS简单请求:

  • 请求方式:
    • HEAD
    • GET
    • POST
  • HTTP头信息:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:application/x-www-form-urlencoded或multipart/form-data或text/plain

只要满足上述条件之一就是简单请求。

简单请求:

在头信息中添加Origin字段。

  • Access-Control-Allow-Origin必须填写,具体值或*
  • Access-Control-Allow-Credentials可选,是否允许发送cookie,设置为true表示默认在请求之中。
  • Access-Control-Expose-Headers:可选,拿到其他字段。
Fetch解决跨域:

主要方法也是设置请求头实现跨域(Access-Control-Allow-Origin)。

fetch返回一个Promise对象,因此需要使用then取得返回结果。

//前端使用fetch关键字
 fetch('http://localhost:8090/api/data?cb=getData', { //请求地址
   method: 'GET',//请求方式
   mode: 'cors' //请求模式(跨域)
   }).then(res => {
     return res.json();
   }).then(res => {
     console.log(res.data);
 })
 
 //后端设置响应头
  res.writeHead(200,{
 'Access-Control-Allow-Origin':'*'
 })

当然也可以将回调函数改为async/await 形式:

 async function getData() {
   try {
     let response = await fetch('http://localhost:8090/api/', {
     method: 'POST',
     body:JSON.stringify({name:'www'}),
     mode: "cors"
   });
     return await response.json();
   } catch (error) {
     console.log('Request Failed', error);
   }
 }
 
 async function data() {
 let data = await getData();
 console.log(data.data);
 }

 data();

复杂请求;

在实际请求钱,增加一次HTTP查询请求。
在简单请求中我们只需要设置Access-Control-Allow-Origin字段即可。但在复杂请求中我们需要设置不同请求头。

CORS优缺点:

优点:

  • 支持所有类型的HTTP请求
  • 可以通过onerror监听错误

缺点:

  • 兼容性不好,IE10以下不支持
更多内容请看:IFTS