Nginx反向代理來解決跨域問題

參考如下博客,自己小小總結了下跨域的一些問題:
什麼是跨域
瀏覽器爲什麼要設計同源策略
什麼是跨域?如何解決

跨域的概念

一個域下的文檔或者腳本(比如ajax) 去請求另外一個域的資源。
這裏判斷是否在一個域的,依據三點: 協議(http|https) + 域名 + 端口 ,如果中間 有任一個不同,那麼就算是跨域請求。
注意: 如果兩個域名指向同一個ip ,那也算是跨域請求!

我們來看下面的頁面是否與 http://store.company.com/dir/index.html 是同源的?
http://store.company.com/dir/index2.html 同源
http://store.company.com/dir2/index3.html 同源 雖然在不同文件夾下
https://store.company.com/secure.html 不同源 不同的協議(https)
http://store.company.com:81/dir/index.html 不同源 不同的端口(81)
http://news.company.com/dir/other.html 不同源 不同的域名(news)

跨域的原由

主要是因爲瀏覽器的設定了同源策略(SOP)。
不同的域下存着不同的數據,例如cookie 等,發送同域的請求,cookie 會自動攜帶上,如果是不同域的請求,因爲有了同源策略,那麼cookie 是無法攜帶的 且 發送不同域的請求也是被攔下來的。

思考一下,如果沒有SOP ,當請求到跨域的網站時,那個網站就能獲取到源網站的一些cookie 信息了,要知道 cookie 裏有時候存儲的都是用戶信息,比如sessionId , 若對方網站是一個惡意網站,很輕鬆地就能獲取到你的sessionId ,然後進行連接攻擊了。

注意: 一些加載圖片、js、css等資源是不違背同源策略的,比如 http://phone.happy.com 裏需要展示 http://img.happy.com/xxx.png 是可行的。如果是訪問接口 , 就可能違背。

跨域的實際例子

一個APP應用開發,前端使用H5 做頁面 , 後端提供APP的接口 即可。2個項目都部署到同一臺服務器上,分配不同域名,並且都部署到nginx上。

前端 後端
域名 http://phone.happy.com http://api.happy.com

前端項目請求後端接口時,從http://phone.happy.com 訪問http://api.happy.com的時候,就是一個跨域請求,一般在瀏覽器F12模式下,可以看到類似類似類似下圖的錯誤日誌:
在這裏插入圖片描述
那麼如何解決這種問題呢?請耐心地看下文。

解決跨域的辦法

網上也有很多解決辦法,是從前端着手的。額,我自己的解決辦法就是通過Nginx的代理。當Nginx 接收到前端需要請求後端接口時,將前端請求轉到後端接口服務上即可。

需要注意的是,在我的後端接口項目的context-path 我設定的是 /happyapi (/+項目名+api),儘量和 前端 裏的一些路由不要衝突吧。

實戰

主要就是在nginx上配置下就好了

。。。省略
http{
	#上游服務器-接口項目
    upstream happyapi{
	  server localhost:9099 weight=1 max_fails=1 fail_timeout=3s;
    }
	#接口項目
	server{
		listen 80; #服務端口號,也就是nginx的port
		server_name api.happy.com; #服務器的域名
		location /{
			proxy_pass http://happyapi; #轉到上游服務器
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			。。。省略
		}	
    }
	#前端H5項目
	server{
		listen 80;
		server_name phone.happy.com;
		#h5項目
		location /{
			root /usr/local/happy/dist;
			index index.html;
			try_files $uri $uri/ /index.html;
		}
		#h5項目裏的字體格式
		location ~* /.(eot|ttf|ttc|otf|eot|woff|woff2|svg)$ {
              root /usr/local/happy/dist;
	    }
	    #攔截到api的請求,代理轉發到接口項目
	    location /happyapi/{
			proxy_pass http://happyapi; #對應upstream
        }
	}
}

核心內容:

 #攔截到api的請求,代理轉發到接口項目
	    location /happyapi/{
			proxy_pass http://happyapi; #對應upstream
        }

所以如果前端發送 http://phone.happy.com/happyapi/user/login 的請求時,Nginx 會攔截並轉發到 http://api.happy.com/happyapi/user/login 上 ,也就是真正的接口項目了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章