几种跨域处理方式

1.img,iframe等标签

如< iframe src=”a.com?id=1”>。对于只要发请求,不需要回调操作的很适合用这种方式。把请求发出去就不管了。

2.JSONP

其实是生成一个script标签,因为script标签本身是跨域的。只支持GET请求。
用script标签拿到包裹了数据的方法(相当于是返回了一段js代码),比如回调函数是fnA(data),那么服务端返回的是fnA({status:1,data{}})。然后script标签拿到返回的js代码就可以直接运行回调。
需要前后端代码的一个规范。后端要拿到回调函数名。并处理成前端需要的js代码。

3.CORS

需要浏览器和服务器都支持。
相当于是服务端说明一下我允许来自哪个域的请求。要一些服务端配置。
前端ajax代码几乎不需要修改。

4.服务端代理

让本域的服务端去请求跨域的数据。然后返回过来到前端。主要是服务端的工作。
对前端来讲,就是一个非跨域的请求。
以nodejs为例,下面的代码可以实现使用
http://localhost:8300/news-at/api/4/news/latest
获取
http://news-at.zhihu.com/api/4/news/latest
这个接口的的数据

var proxyMiddleware = require('http-proxy-middleware')
var express = require('express')
var app = express()
app.use(proxyMiddleware('/news-at', {
  target: 'http://news-at.zhihu.com',
  changeOrigin: true,
  pathRewrite: {
    '^/news-at/api': '/api', // rewrite path 
  }
}))

5.使用form、iframe与后台配合。代理模式。

原理:form表单提交可以跨域。form表单提交之后其实是会跳转页面的。将其跳转到一个iframe中去。
如果提交后的页面保持是b域,那么a域依然无法访问iframe的。

从a域发到b域的请求在b域中被处理后重定向到a域的将请求结果和回调函数名放到b域的代理页面中去处理。

所以iframe回到了a域。就没有跨域了。 在iframe中可以互相访问了,可以在iframe中调用它的parent中的函数。

缺点:因为是把数据放到链接中的。url的长度是有限制的。所以处理之后返回的数据的大小是有限制的。
优点:可发送post请求。

本域:a.com\page_a 代理页面:a.com\page_b
外域:b.com

a.com\page_a,也就是我们发起请求的页面。

<iframe src="" name="proxyIframe" id="proxyIframe"></iframe>
<form action="http://b.com" method="post" target="proxyIframe">
    <input type="text" name="proxyPage" value="http://a.com/page_b">
    <input type="text" name="callback" value="alert">
    <input type="submit" value="提交">
</form>

b.com后台处理我们的请求:

<?php 
$proxyPage = $_POST['proxyPage'];
$callback = $_POST['callback'];
$returnData = ['status'=>1,'data'=>['info' => '操作成功!',]];
//把操作的结果放到发送请求的域内的一个代理页面。
$url = $proxyPage."?callback=".$callback."&arg=".json_encode($returnData);
//跳转到http://a.com/page_b?callback=alert&arg={"status":1,"data":{"info":"\u64cd\u4f5c\u6210\u529f!"}}
header("Location:".$url);
?>

a.com\page_b:在iframe中执行。拿到链接上的b域的返回结果和回调函数。运行回调。

    // 会在iframe中执行
    if(parent == self){
        return;
    }
    var href = location.href;
    var callback = href.callback;//伪代码
    var arg = href.arg;//伪代码
    arg = JSON.parse(arg);
    var parentFn = parent[callback];
    if(typeof parentFn == 'function'){
        parentFn(arg);
    }

这个方法是在 张容铭的《JavaScript设计模式》第十一章代理模式中看到的。

6.document.domain 用于跨子域

7.WebSocket

8.HTML5 postMessage 一般用于iframe之间。

9.location.hash。window.name。https://www.cnblogs.com/vajoy/p/4295825.html

其他

  • 跨域时cookie的情况。
  • 其他处理跨域的方式比较。
  • 服务端调用其他域接口与前端调用的区别。
  • 正向代理与反向代理

同步更新:https://github.com/liusaint/JavaScript-record/issues/1

发布了72 篇原创文章 · 获赞 109 · 访问量 48万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章