1. 程式人生 > >【Angular】angular 跨域解決方案詳解

【Angular】angular 跨域解決方案詳解

瀏覽器對於javascript的同源策略的限制,例如a.cn下面的js不能呼叫b.cn中的js,物件或資料(因為a.cn和b.cn是不同域),所以跨域就出現了:

簡單的解釋就是相同域名,埠相同,協議相同

同源策略:
請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名,埠,協議相同.

如果我在本地上的域名是study.cn,請求另外一個域名一段資料

這個時候在瀏覽器上會報錯

這個就是同源策略的保護,如果瀏覽器對javascript沒有同源策略的保護,那麼一些重要的機密網站將會很危險~

  • 反向代理

反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。
Angular跨域
Angular專案分為工程程式碼和生產程式碼,在本地除錯一般都是工程程式碼,這樣聯調介面的話,每次寫一個介面都要丟到伺服器上測試,嚴重影響效率,所以我們需要做的就是能在工程專案上聯調介面,隨時能看到效果,但是後端程式碼不是部署在本機的話就會有跨域問題,於是我們便需要去著重去解決跨域問題!這樣後端程式碼隨時改,前端也可以隨時更改看到效果,實現真正的前後端分離!
對於Angular解決跨域問題,應該是開發者已經想到這個問題,所以解決這個問題很簡單!那就是反向代理!!
下面介紹反向代理的方法:
首先需要建立一個JSON檔案,檔名”
proxy.config.json

{
"/api":{
"target":"http://106.15.179.92"
}
this.$http.post(`/api/front/frontUserController/login.do`,data)
.then(res=>{
Console.log(res);
})

然後配置”package.json 檔案

"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.config.json",
"build": "ng build --prod --aot",
"test": "ng test"
, "lint": "ng lint", "e2e": "ng e2e"

甩鍋解決跨域辦法
跨域?和我們前端有關係?有嗎?沒有吧!我不解決,我就不解決,你們後端去解決!
現在介紹一種對於任何專案都通用的解決跨域的方法!
用nginx反向代理實現跨域,是最簡單的跨域方式。只需要修改nginx的配置即可解決跨域問題,支援所有瀏覽器,支援session,不需要修改任何程式碼,並且不會影響伺服器效能。
我們只需要配置nginx,在一個伺服器上配置多個字首來轉發http/https請求到多個真實的伺服器即可。這樣,這個伺服器上所有url都是相同的域名、協議和埠。因此,對於瀏覽器來說,這些url都是同源的,沒有跨域限制。而實際上,這些url實際上由物理伺服器提供服務。這些伺服器內的javascript可以跨域呼叫所有這些伺服器上的url。
下面,給出一個nginx支援跨域的例子,進行具體說明。
如,我們有兩個pythonflask開發的專案:testFlask1和testFlask2。
testFlask2專案上的javascript指令碼要通過ajax方式呼叫testFlask1的一個url,獲取一些資料。
正常情況下部署,就會有跨域問題,瀏覽器拒絕執行如下這樣的呼叫。

$("button").click(function () {
$.get("127.0.0.1:8081/partners/json", function (result) {
$("div").html(result);
});

下面把testFlask2專案的javascrip檔案修改一下。這樣訪問同源的url,就不會有跨域問題。

$("button").click(function () {
$.get("partners/json", function (result) {
$("div").html(result);

但是,我們testFlask2專案實際上沒有partners/json這樣的url,那怎麼處理呢?
我們這樣編寫nginx的配置檔案:

server{
listen8000;
location/ {
includeuwsgi_params;
uwsgi_passunix:/tmp/testFlask2.sock;
location/partners {
rewrite^.+partners/?(.*)$ /$1 break;
uwsgi_passunix:/tmp/testFlask1.sock;

我們把testFlask2專案部署在8080埠的根目錄下。把提供web服務的testFlask1專案部署在/partners目錄下。
但我們的testFlask1專案並不能處理/partners/json這樣的url請求。那怎麼辦呢?
通過rewrite^.+partners/?(.*)$ /$1 break; 這一條命令,nginx可以把收到的/partners/請求全部轉為/請求後再轉發給背後的真實web伺服器。
這樣,RESTFUL的ajax客戶端程式,只需要給出特定字首的url就可以呼叫任意伺服器提供的RESTFUL介面了。
甚至,通過nginx的反向代理,我們還能呼叫其他公司開發的網站提供的RESTFUL介面。
如,

location/sohu {
rewrite^.+sohu/?(.*)$ /$1 break;
proxy_passhttp://www.sohu.com/;

我們就把sohu網站整個搬到我們的8080:/sohu/目錄下了,我們的javascript就可以盡情呼叫其RESTFUL服務了。
順便說一下,rewrite^.+sohu/?(.*)/1 break; 這句命令中,1(.)()1,第二對()內的引數就是$2,以此類推。

angular、spring cloud 開源實戰專案原始碼:https://gitee.com/xfdm/FCat
QQ群:549141844

程式碼持續更新…