日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

跨域问题的前后端解决方案

發(fā)布時間:2025/3/21 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 跨域问题的前后端解决方案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

跨域問題是開發(fā)過程中一個比較常見的問題,無論你是前臺開發(fā),還是后臺開發(fā),可能都處理過這個問題。本文主要是介紹跨域常用的解決方案。

什么是跨域?

假設(shè)有這么一個場景,我有一個網(wǎng)站,在里面有一個顯示商品的功能,對應(yīng)的頁面地址是:

http://www.myexample.com/page/page-a.html

在實現(xiàn)這個頁面時,我通過iframe集成了另外一個網(wǎng)站的商品展示功能,對應(yīng)的頁面地址是:

http://www.othersite.com/page/show.html

頁面看起來可能是這樣的,我簡化了所有的內(nèi)容,通過不同的背景色來區(qū)分不同的頁面。

可以想象,我并沒有做太多的開發(fā),就擁有一個商品展示功能了。但是在page-a頁面中,并不能通過Javascript來訪問show頁面的document、cookie等對象,不能修改show頁面中的任何內(nèi)容。代碼看起來是這樣的,運(yùn)行的時候會產(chǎn)生錯誤:

document.getElementById("iframe").contentWindow.document;

// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.

為什么這樣設(shè)計?

我們反過來思考,如果可以訪問document、cookie,會出現(xiàn)什么問題?

可以通過Javascript來監(jiān)聽show頁面上的輸入框,可以改變表單提交的URL。在myexample這個網(wǎng)站就可以做任何事情了,截獲用戶的敏感數(shù)據(jù)了,比如登錄信息、個人喜好等數(shù)據(jù)。結(jié)果就是,在你訪問一個網(wǎng)站的時候,你的數(shù)據(jù)很容易就被泄露了,包括用戶名和密碼。

所以,簡單地說就是安全,在WWW創(chuàng)立之初,設(shè)計者就考慮到了這個問題,通過一些策略來保證用戶信息的安全,防止惡意的網(wǎng)站竊取數(shù)據(jù)。

A web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, hostname, and port number.

這個叫同源策略(wiki),所有的瀏覽器都支持這個安全策略。從上面的定義來看,同源指的是三個相同:
1、協(xié)議(scheme)相同
2、域名(hostname)相同
3、端口(port)相同

這里又要引入一個新的概念:

URI(wiki)

Uniform Resource Identifier (URI) is a string of characters used to identify a resource.

具體的語法如下圖所示:
?

同源概念中的scheme、host、port對應(yīng)到上圖中的結(jié)構(gòu),回到我們剛才的例子:

http://www.myexample.com/page/page.html
1、scheme是http
2、host是www.myexample.com
3、port沒有表示是80

這樣就很容易理解了,跨域就是不同源,兩個不同源的網(wǎng)站相互會被限制,限制有三種:

1、Cookie、LocalStorage 和 IndexDB 無法讀取。
2、DOM無法獲得。
3、AJAX請求不能發(fā)送。

前端解決方案

1、修改Domain

瀏覽器允許通過設(shè)置document.domain共享 Cookie,相當(dāng)于是把兩個不同源的頁面設(shè)置成相同的源,這種方法只適用于 Cookie 和 iframe 窗口,而且要求兩個網(wǎng)頁一級域名相同,只是二級域名不同。

document.domain='example.com';

2、window通信

這個方案簡單的說,就是通過DOM的window對象來傳遞參數(shù)。阮一峰老師總結(jié)了三點,非常清晰,我就不重復(fù)的去寫了:

片段標(biāo)識符(fragment identifier)
window.name
跨文檔通信 API(Cross-document messaging)

詳情見:參考資料4

3、JSONP

在一個頁面中,可以使用<script>標(biāo)記來引用一個外部的JS文件,并且能夠成功執(zhí)行。直接上代碼可能會更好理解一些。

假設(shè)我在某個網(wǎng)站有一個js文件,URL是:http://remoteserver.com/remote.js,里面的代碼很簡單:

alert('this is a remote alert!');

在另外一個網(wǎng)站的頁面http://localserver.com/page.html,可以引入這個JS文件:

<head>
? ? <script type="text/javascript" src="http://remoteserver.com/remote.js"/>
</head>

在瀏覽器中打開page.html,會彈出一個警告對話框。

JSONP就是利用了這一點,如果將alert的內(nèi)容改為下面的內(nèi)容:

localMethod({"result":"data from remote!"});

同時將page.html的內(nèi)容修改一下

<script type="text/javascript">
? ? function localMethod(data){
? ? ? ? alert(data.result);
? ? }
</script>
<script type="text/javascript" src="http://remoteserver.com/remote.js">

再次運(yùn)行,alert的內(nèi)容就是:data from remote!

而script元素是可以通過document.createElement('script')動態(tài)創(chuàng)建的,也就具備了隨時可以引入一個外部script,這樣就達(dá)到了跨域訪問的目的,但是JSONP只支持GET請求,其他的方式不支持。

4、WebSocket

WebSocket是一種通信協(xié)議,不實行同源政策,詳情見參考資料4。

上面的幾種方法,可以說是奇技淫巧,繞過了瀏覽器的限制。隨著前端框架的興起,以及前后端分離架構(gòu)的流行,上面的技巧已經(jīng)比較陳舊了。

后端解決方案

1、URL轉(zhuǎn)發(fā)

在同一個窗口中,通過URL提交的方式,多次跳轉(zhuǎn),需要兩邊的頁面相互支持。

比如在http://www.myexample.com/page/page-a.html頁面中,有一個提交按鈕,將數(shù)據(jù)post到遠(yuǎn)端的服務(wù)器,需要告訴對方跳轉(zhuǎn)回來到哪個頁面,看起來像這樣:

http://www.othersite.com/page/show.html?url=http://www.myexample.com/page/page-b.html

遠(yuǎn)程服務(wù)器show.html處理完成后,再次將數(shù)據(jù)提交到page-b.html,page-a和page-b是在同一個域下面的,所以就可以相互訪問了。

2、HTTP代理

原理就是把遠(yuǎn)程服務(wù)通過代理服務(wù)器變成本地的服務(wù),需要借助WEB服務(wù)器,Nginx和Apache都支持代理轉(zhuǎn)發(fā)。Nginx的配置參考:

location /api/proxy {
? ? proxy_pass? http://remoteipaddress:8080/api;
? ? proxy_set_header? Host? $host;
? ? proxy_set_header? X-Real-IP? $remote_addr;
? ? proxy_set_header? X-Forwarded-For? $proxy_add_x_forwarded_for;
}

Node也有開源的組件http-proxy-middleware可以支持代理。

var express=require('express');
var proxy=require('http-proxy-middleware');
var app=express();
app.use('/api',proxy({target:'http://www.example.org', changeOrigin:true}));
app.listen(3000);

?

3、CORS

詳情見參考資料5,非常詳細(xì),這里補(bǔ)充一個交互示意圖,幫助理解。

以上這些就是跨域的常見解決方案,其中CORS是終極解決方案,可以適用于多種場景。

?

參考資料:

1.https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
2.https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
3.https://www.w3.org/TR/cors/
4.http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
5.http://www.ruanyifeng.com/blog/2016/04/cors.html



作者:大家叫我杰哥
鏈接:https://www.jianshu.com/p/fccabaf38ac2
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

總結(jié)

以上是生活随笔為你收集整理的跨域问题的前后端解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。