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的情況。
- 其他處理跨域的方式比較。
- 服務端調用其他域接口與前端調用的區別。
- 正向代理與反向代理