前端跨域总结
一、通过document.domain + iframe实现
二、通过location.hash + iframe实现
三、通过window.name + iframe实现
四、通过HTML5的postMessage方法实现
上面三种方法都属于破解,HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。
这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。
举例来说,父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法就可以了。
var popup = window.open( 'http://bbb.com' , 'title' ); popup.postMessage( 'Hello World!' , 'http://bbb.com' ); |
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。
子窗口向父窗口发送消息的写法类似。
window.opener.postMessage( 'Nice to see you' , 'http://aaa.com' ); |
父窗口和子窗口都可以通过message事件,监听对方的消息。
window.addEventListener( 'message' , function (e) { console.log(e.data); }, false ); |
message事件的事件对象event,提供以下三个属性。
event.source:发送消息的窗口
event.origin: 消息发向的网址
event.data: 消息内容
下面的例子是,子窗口通过event.source属性引用父窗口,然后发送消息。
window.addEventListener( 'message' , receiveMessage); function receiveMessage(event) { event.source.postMessage( 'Nice to see you!' , '*' ); } |
event.origin属性可以过滤不是发给本窗口的消息。
window.addEventListener( 'message' , receiveMessage); function receiveMessage(event) { if (event.origin !== 'http://aaa.com' ) return ; if (event.data === 'Hello World' ) { event.source.postMessage( 'Hello' , event.origin); } else { console.log(event.data); } } |
更多内容:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
五、通过jsonp实现
用JSONP获取的不是JSON数据,而是可以直接运行的JavaScript语句。
示例代码:
站点1,用来跨域请求的目标地址:http://localhost:8098/index.aspx
index.aspx.cs处理逻辑实现:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace JSONPTest1 { public partial class index : System.Web.UI.Page { protected void Page_Load( object sender, EventArgs e) { //模拟数据 string jsonData= "{\"IsSuccess\":true,\"Message\":\"承保成功\",\"result\":{\"TransRefGUID\":\"YSYJY201711211118578452\",\"Code\":\"22201711211106260661645\",\"Id\":\"368\"}}" ; string callBack = Request.QueryString[ "callback" ]; Response.Write(callBack + "(" + jsonData + ")" ); Response.End(); } } } |
站点2,发送跨域请求的地址:http://localhost:8199/index.aspx
这个页面中,有三种方式实现跨域访问:
1、通过script标签指向
< script type="text/javascript"> //通过script标签指向跨域地址时,需要执行的回调函数 function callbackProcess(data) { alert(JSON.stringify(data)); } </ script > <!--通过script标签指向实现--> < script type="text/javascript" src="http://localhost:8098/index.aspx?callback=callbackProcess"></ script > |
2、通过jQuery的$.ajax方法
< script src="Scripts/jquery-1.8.2.min.js"></ script > < script type="text/javascript"> //通过jQuery的全局方法$.ajax实现 var url = "http://localhost:8098/index.aspx"; $.ajax({ url: url, //这里虽设置为POST,但其实还是走的GET方式, //因为要请求的页面是用Request.QueryString["callback"]来接收参数的,如果POST有效的话,那请求就会报错了, //所以,正常执行就说明其实走的是GET。 type: "POST", dataType: "jsonp", //告诉服务器通过什么字段获取回调函数的名称 //如果设置的值与跨域请求的目标要接收的参数值不一致,则会报错,执行error jsonp: "callback", //声明本地回调函数的名称 jsonpCallback: "callbackProcess", success: function (data) { alert("ajax success callback: " + JSON.stringify(data)) }, error: function (jqXHR, textStatus, errorThrown) { alert(textStatus + ' ' + errorThrown); } }) </ script > |
3、通过jQuery的getJSON方法
< script src="Scripts/jquery-1.8.2.min.js"></ script > < script type="text/javascript"> //通过jQuery的getJSON方法实现 var url = "http://localhost:8098/index.aspx"; $.getJSON(url+"?callback=?", {}, function (data,textStatus,jqXHR) { alert("data:" +JSON.stringify(data) + "\ntextStatus:" + textStatus); }) </ script > |
以上三种方式执行的结果大致是这样的:
jsonp缺点:
1、只能使用 GET 方法发起请求,这是由于 script 标签自身的限制决定的。
2、不能很好的发现错误,并进行处理。与 Ajax 对比,由于不是通过 XmlHttpRequest 进行传输,所以不能注册 success、 error 等事件监听函数。
(这点只针对第1种方式,2、3种可以监听success、 error)
六、通过CORS实现
CORS(Cross-Origin Resource Sharing)跨域资源共享。
IE10+
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
更多内容:http://www.cnblogs.com/zhaow/articles/9056089.html
CORS和JSONP对比
1、JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。
4、CORS与JSONP相比,无疑更为先进、方便和可靠。
七、 nginx代理跨域
八、 nodejs中间件代理跨域
九、 WebSocket协议跨域
参考资料:
http://www.ruanyifeng.com/blog/2016/04/cors.html
https://mp.weixin.qq.com/s/NOmsbKZsryTUONQj2gBFIA
http://mp.weixin.qq.com/s/CZgz0ya_RXhzDkEfv2_9iw
https://funteas.com/topic/59f6f16dadc582cf09ba794f
http://mp.weixin.qq.com/s/nZ26szrbNVQMwAo0rl3U9g
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端