博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多种跨域方案
阅读量:4493 次
发布时间:2019-06-08

本文共 4228 字,大约阅读时间需要 14 分钟。

同源策略

说到跨域就离不开浏览器的同源策略

  • 协议
  • 域名
  • 端口号

只要有一个不同,就是跨域

非同源下

非同源下,三种行为会受到限制

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得
  • AJAX 请求不能发送

跨域最常用的方案

  • jsonp(只能发送get请求)
  • cors
  • postMessage
  • document.domain
  • location.hash
  • http-proxy
  • nginx
  • websocket

自己实现一个jsonp

jsonp实际上返回的是一个函数调用

function jsonp(url,data,callback){    var scriptObj = document.createElement('script');    var head = document.getElementsByTagName('head')[0];    var fnName = 'jquery_'+new Date().getTime();    var arr = []    for(var key in data){        console.log(key)        arr.push(key+'='+data[key]);    }    data = arr.join('&');    window[fnName] = function(json){        callback(json);    }    scriptObj.src = url + '?' + data + '&'+callback+'='+fnName;    head.appendChild(scriptObj);}jsonp('http://10.252.55.52:1337/user/socialInfo',{    page:1,    pageList:5,    type:1},function(data){    console.log(data)})function jsonp({url,params,cb}){    return new Promise((resolve,reject)=>{        window[cb] = function(data){            resolve(data)        }        params = {...params,cb}        let arrs = [];        for(let key in params){            arrs.push(`${key}=${params[key]}`)        }        let script = document.createElement('script')        script.src = `${url}?${arrs.join('&')}`        document.body.appendChild(script)    })}jsonp({    url:'',    params:{},    cb:'show'}).then(data=>{    console.log(data)})复制代码

cors

cors方式解决跨域问题,往往是需要在服务端设置一些请求头

我们可以通过 req.headers.origin 获取origin

下面是常用的一些请求头的设置

setHeader('Access-Control-Allow-Origin':origin) //允许哪个源可以访问我

setHeader('Access-Control-Allow-Headers':) //允许携带哪个头访问我

setHeader('Access-Control-Expose-Headers':) //允许返回的头

setHeader('Access-Control-Allow-Methods':) //响应标头指定响应访问所述资源到时允许的一种或多种方法

setHeader('Access-Control-Max-Age':) //用来指定本次预检请求的有效期,单位为秒

setHeader('Access-Control-Allow-Credentials':true)

postMessage

postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

举例

假如有一个页面a.html 位于 在a.html 通过iframe嵌入b.html,b.html位于www.domain.com下

复制代码

如果a.hhtml想和iframe通讯的话,可以如下操作

let frame = doucument.getElementById('frame') //想和谁通讯,就先获取这个窗口,此时我们需要的iframe里的windowframe.contentWindow.postMessage('你好啊',http://www.domain.com) //发送消息,后面要写明是给哪个域发的复制代码

在b.html接收

wondiw.onmessage = function(e){    console.log(e.data)    e.source.send('我不好',e.origin) //再回复消息}或者document.addEventListener('message',  function(e){   // content.....    })复制代码

document.domain

利用document.domain 实现跨域:

前提条件:这两个域名必须属于同一个一级域名,而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域.

例如:

是可以的。

下指到 是可以的。

但是

下指到 是不行的。

指到 还是不行的

如果我们要在当前页面下,“ 下上传图片到 "" 下去

需要在两个页面都写上

if(document.domain !='sojson.com'){    document.domain = 'sojson.com';}复制代码

对于这个方案我的理解是

有一个a.html 位于www.test.com下

有一个b.html 位于www.domain.com下

两个页面想通讯的话

我们需要在a.html页面引入一个iframe

let first = true //是否第一次加载function load(){    if(first){        let iframe = document.getElementById('frame')        iframe.src='http://www.test.com/b.html' //最后必须把b.html设置为和a.html同域名的,这样才能获取iframe.contentWindow.name,不然会受同源策略的影响        first = false    }else{        console.log(iframe.contentWindow.name)    }}复制代码

iframe.contentWindow.name就可以获取到这个数据了

在b.html我们可以把想传递的数据放到 window.name上

window.name='你好啊'

location.hash

有一个a.html 位于www.test.com下

有一个c.html 位于www.domain.com下

现在a.html想访问c.html

a.html

wondiw.onhashchange = function(e){    }或者document.addEventListener('hashchange',  function(e){   // content.....    })复制代码

c.html

console.log(window.location.hash) //获取这个hash值let iframe = document.createElement('iframe')iframe.src='http://www.test.com/b.html#idontloveyou"'document.body.appendChild(iframe)复制代码

b.html

window.parent.parent.location.hash = location.hash复制代码

websocket

websocket属于高级api,平常我们一般都使用socket.io去进行兼容

服务端需要先安装ws

服务端代码如下:

let WebSocket = require('ws')let wss = new WebSocket.Server({port:3000})wss.on('connection',function(ws){    ws.on('message',function(data){ //服务端接收消息        console.log(data)        ws.send('我不好') //服务端发送消息    })})复制代码

客户端代码如下:

let socket = new WebSocket('ws://localhost:3000')socket.onopen = function(){    socket.send('你好啊')}socket.onmessage = function(e){    console.log(e.data) // 客户端接收消息}复制代码

nginx

首先安装nginx

如果是mac的话

brew install nginx //安装nginx

nginx.conf //配置文件

下面是一些常用的配置

add_header "Access-Control-Allow-origin" "*"

转载于:https://juejin.im/post/5c205345518825444612d311

你可能感兴趣的文章
easyui-datagrid 自适应列宽问题
查看>>
OO第一次总结
查看>>
【导图控】各软件开发版本详解
查看>>
SharePoint【ECMAScript对象模型系列】-- 11. Enable/Disable Ribbon上的Button
查看>>
Spring数据访问1 - 数据源配置及数据库连接池的概念
查看>>
setting.xml配置详解
查看>>
window系统下调度数据库类型资源库中的kettle job
查看>>
monkey 命令详解
查看>>
图像预处理
查看>>
16个Web开发的IDE
查看>>
Java动态代理与Cglib库
查看>>
libevent源码深度剖析一
查看>>
SSH隧道技术简介
查看>>
PAT乙级1025
查看>>
找的好网站(macdow语法,扫描二维码,)
查看>>
浏览器插件开发遇到的问题
查看>>
EF Core 1.0 和 SQLServer 2008 分页的问题
查看>>
BZOJ1798: [Ahoi2009]Seq 维护序列seq
查看>>
PS--人物黄金色调
查看>>
开启ucosii的移植之旅
查看>>