1. 程式人生 > >Nginx配置跨域訪問

Nginx配置跨域訪問

由於瀏覽器同源策略的存在使得一個源中載入來自其它源中資源的行為受到了限制。即會出現跨域請求禁止。

通俗一點說就是如果存在協議、域名、埠或者子域名不同服務端,或一者為IP地址,一者為域名地址(在跨域問題上,域僅僅是通過"url的首部"來識別而不會去嘗試判斷相同的IP地址對應著兩個域或者兩個域是否同屬同一個IP),之中任意服務端旗下的客戶端發起請求其它服務端資源的訪問行動都是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源。

但很多時候我們卻又不得不去跨域請求資源,這個時候就需要我們想方法去繞過瀏覽器同源策略的限制了。

常見的跨域請求解決方法:

1.

Jsonp 利用script標籤發起get請求不會出現跨域禁止的特點實現
2.window.name+iframe 藉助中介屬性window.name實現
3.Cors需要伺服器設定header:Access-Control-Allow-Origin
4.Nginx反向代理 可以不需要目標伺服器配合,不過需要Nginx中轉伺服器,用於轉發請求(服務端之間的資源請求不會有跨域限制)

Nginx跨域訪問解決方案

使用Ajax跨域請求資源,Nginx作為代理,出現以下錯誤:

The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed

解決方法:
使用Nginx作為反向代理伺服器,並在配置中對應的location下新增上如下的設定

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header Cache-Control private;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

完整配置如下:

server {
	listen       80; 
	server_name  192.168.16.190;
	root   /home/fastdfs/file/data;
	index  index.htm index.html;
	add_header 'Access-Control-Allow-Origin' '*';
	add_header 'Access-Control-Allow-Credentials' 'true';
	add_header Cache-Control private;
	add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
	add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
	
	location / {
		# 此處用於處理 H5 的 History時 重寫的問題
		if (!-e $request_filename) {
			rewrite ^(.*) /index.html last;
			break;
		}
	}
	
	# 代理服務端介面
	location /api {
		if ($request_method = 'OPTIONS') {
			add_header Access-Control-Allow-Origin *;
			add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
			return 200;
		}
		proxy_pass http://192.168.16.191:3000/api;   #將真正的請求代理到API 服務地址
	}
	
	location ^~/cross_origin/ {
		rewrite ^/cross_origin/(.*)$ /$1 break;
		if ($request_method = 'OPTIONS') {
			add_header Access-Control-Allow-Origin *;
			add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
			return 200;
		}
		proxy_pass http://192.168.16.191:3000/cross_origin ;   #將真正的請求代理到API 服務地址
	}
}	

服務端允許跨域配置:

#region 設定允許跨域,允許複雜請求
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
	HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS");
	HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
	//HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
	HttpContext.Current.Response.End();
}
#endregion

備註: 如果伺服器設定了允許跨域,使用Nginx代理裡面就不需要了(或者就不用使用Nginx了)

大家可以參考這個Nginx文件:http://nginx.org/en/docs/http/ngx_http_headers_module.html
cores裡面引數含義請參考:https://blog.csdn.net/m0_37886429/article/details/83617880