幾種跨域處理方式

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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章