跨域

跨域!!

什么情况造成跨域?

同源策略限制 不同源会造成跨域。以下任意一种情况不同,都是不同源。

  • http://协议不同
  • www子域名不同
  • baidu.com主域名不同
  • 8080端口号不同
  • www.baidu.comip地址和网址不同

跨域解决方案

jsonp , cors , Nginx

jsonp

只能解决 GET 跨域

  • 原理:同源策略不能请求不同域的数据,但是可以引入不同域的js脚本。因为所有的src属性和href属性都不受同源策略限制。可以载入js脚本,然后触发回调函数,将json数据作为参数传入函数进行处理。
  • 步骤:
    • 创建script标签
    • script的src属性设置接口地址
    • 接口参数,必须要带一个回调函数 要不然后台无法返回数据。
    • 通过回调函数去接收后台返回数据
//去创建一个script标签
var  script = document.createElement("script");
//script的src属性设置接口地址 并带一个callback回调函数名称
script.src = "http://127.0.0.1:8888/index.php?callback=jsonpCallback";
//插入到页面
document.head.appendChild(script);
//通过定义函数名去接收后台返回数据
function jsonpCallback(data){
    //注意  jsonp返回的数据是json对象可以直接使用
    //ajax  取得数据是json字符串需要转换成json对象才可以使用。
}

封装一个jsonp函数:

function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) => { //返回一个promise对象
    let script = document.createElement('script')   //新建一个script
    window[callback] = function(data) {
      resolve(data)
      document.body.removeChild(script)
    }
    params = { ...params, callback } // wd=b&callback=show
    let arrs = []
    for (let key in params) {
      arrs.push(`${key}=${params[key]}`)
    }
    script.src = `${url}?${arrs.join('&')}`
    document.body.appendChild(script)
  })
}
jsonp({
  url: ' ',
  params: {  },
  callback: ' 
}).then(data => {
   //其他处理
})
  • jquery 的jsonp形式
$.ajax({ 
    url:"http://crossdomain.com/jsonServerResponse", 
    dataType:"jsonp", 
    type:"get",//可以省略 
    jsonpCallback:"show",//->自定义传递给服务器的函数名,而不是使用jQuery自动生成的,可省略
    jsonp:"callback",//->把传递函数名的那个形参callback,可省略 
    success:function (data){ 
        console.log(data);
    } 
});

CORS:跨域资源共享

支持 XmlHttpRequest 的跨域请求。

  • 原理:服务器设置 Access-Control-Allow-Origin 的HTTP响应头之后,浏览器将会允许跨域请求
  • 限制:浏览器需要支持HTML5,可以支持POST,PUT等方法兼容ie9以上
    需要后台设置
    Access-Control-Allow-Origin: * //允许所有域名访问,或者
    Access-Control-Allow-Origin: http://a.com //只允许所有域名访问
  1. 简单请求
    满足条件:

    • 使用 GET/HEAD/POST
    • Content-Type值为:text/plainmulti,或part/form-data,application/x-www-form-urlencoded
  2. 非简单请求
    在正式请求之前有"预检", 用option方法检查服务器是否支持cors

postMessage()

跨窗口, 页面与iframe,页面与新窗口之间传递数据。

otherWindow.postMessage(message, targetOrigin, [transfer]);

  • message:数据
  • targetOrigin:URI,origin 属性指定哪些窗口可以收到消息

webSocket

HTML5的一个持久化协议,全双工通信,Client 和 Server 都可以主动收发数据。
建立连接时借助HTTP协议,建立后与HTTP无关。
socket.io 封装了 webSocket API。

Node中间件代理

代理服务器转发请求和响应,不受同源限制。

Nginx反向代理

  • 搭建一个中转nginx服务器,用于转发请求

只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能

实现:
通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

window.name + iframe

通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域

location.hash + iframe

页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信

document.domain + iframe

要求二级域名相同

posted @ 2020-04-07 13:38  秋秋秋白  阅读(176)  评论(0编辑  收藏  举报