Nginx跨域
同源策略
何為同源:
1.協議(http/https)相同
2.域名(IP)相同
3.端口相同
詳解請看我另一篇文章
https://www.cnblogs.com/you-men/p/14054348.html
瀏覽器遵循同源策略的目的
同源策略的目的是為了保證用戶信息的安全,防止惡意的網站竊取數據。此策略可以防止一個頁面的
惡意腳本(JavaScript語言編寫的程序)通過該頁面的文檔對象模型來訪問另一網頁上的敏感數據。
同源策略是必需的,否則cookie可以共享,互聯網就毫無安全可言,同源策略僅適用於JavaScript腳本...
換句話說,同源策略不適用與html標簽:
同源策略限制范圍
·cookie、localstorage(本地存儲)和indexDB(數據索引)
·DOM無法獲得
·ajax請求不能發送
同源策略規定,ajax請求只能發送給同源的網址,否則就報錯:
NO 'Access-Control-Allow-Origin' header is present on the requested resource.
跨域
1.什么是跨域:當從A網址的網頁代碼中請求訪問B網站中的數據資源的行為就稱為跨域
2.為何會產生跨域:
目前主流的架構網站技術都是采用前后端分離
前端只負責靜態資源的提供--前端服務器
后端只負責動態資源的提供--后端服務器
靜態資源包含:html頁面,css文件,js文件,圖片等
動態資源就是數據庫中的純數據,如用戶購物車中的商品,或者電商提供的產品的庫存數據等..
一個完整的頁面需要靜態資源與動態資源的組合
通常前端服務器會通過自己靜態頁面中的js代碼向后端服務器請求數據,之后把數據填充到靜態頁面--頁面的渲染。這個過程會產生跨域
模擬nginx跨域
192.168.109.137 nginx 前端服務器
192.168.109.138 nginx + uwsgi 后端服務器
安裝nginx
rpm -ivh nginx-1.16.0-1.el7.ngx.x86_64.rpm
准備前端測試頁面
42.193.126.123 - nginx前端服務器
wangbc.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>歡迎測試nginx跨域:42.193.126.123</title>
<!--js引用-->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<div id=json></div>
<!-- img 標簽直接跨域訪問靜態資源 -->
<img src="http://47.94.149.143/a.jpg">
</body>
<script type="text/javascript">
// AJAX 跨域請求
$.ajax({
type: 'get',
url: 'http://47.94.149.143/api/json',
dataType: 'json',
success: function(res) {
//轉化為字符串
data=JSON.stringify(res)
//添加數據到頁面的div標簽中
$("#json").text(data);
},
error: function(res) {
console.error(res);
}
});
</script>
</html>
准備后端服務器
47.94.149.143 nginx+uwsgi后端服務器
rpm -ivh nginx-1.16.0-1.el7.ngx.x86_64.rpm
配置略改~server配置文件:作為代理並作為一個靜態服務器
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/host.access_localhost.log main;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
location ~* \.(gif|jpg|jpeg|js)$ {
root /static;
}
}
# 創建靜態文件目錄/static並上傳a.jpg圖片
mkdir /static
ls /static/a.jpg
安裝配置uwsgi
yum -y install epel-release python2-devel python2-pip
# 使用pip安裝uwsgi
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple
# 創建應用程序目錄
mkdir -pv /opt/webapp
cd /opt/webapp
# 進入應用程序目錄並創建應用程序文件app.py
headers=('Content-Type', 'application/json;charset=utf-8')
def application(env, start_response):
if env[ 'PATH_INFO' ] == '/api/json':
start_response('200 ok', [headers])
data = '{"name": "shark", "age": 18}'
return [data]
# 繼續在應用程序目錄創建uwsgi的配置文件wbc-uwsgi.ini,添加如下內容
vim wbc-uwsgi.ini
[uwsgi]
socket = 0.0.0.0:8000
chdir = /opt/webapp
wsgi-file = app.py
processes = 2
threads = 2
# 啟動服務
cd /opt/webapp
nohup uwsgi wbc-uwsgi.ini &
# 啟動nginx
systemctl restart nginx
# 檢查端口
ss -ntal | grep 80
解決AJAX跨域請求
有哪些方法:
1.JSONP
2.WebSocket
3.CORS
模擬由於跨域訪問導致的瀏覽器報錯,在nginx代理服務器上設置相應參數解決
CORS是跨源資源共享(Cross-Origin Resource Sharing)的縮寫,W3C標准,是跨源AJAX請求的根本解決方法。
CORS需要瀏覽器和服務器同時支持。目前所有瀏覽器都支持該功能,IE不能低於IE10
整個CORS通信過程,都是瀏覽器自動完成
瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會感知
兩種請求
瀏覽器將 CORS 請求分為兩類:簡單請求(simple request) 和 非簡單請求(not-so-simple request)
** 只要同時滿足以下兩大條件,就屬於簡單請求。否則就是非簡單請求。**
1.請求方法是以下三種方法之一:
·HEAD
·GET
·POST
2.HTTP的頭信息不超出以下幾個字段:
· Accept
· Accept-Language
· Content-Language
· Last-Event-ID
· Content-Type:只限於三個值 application/x-www-form-urlencoded、multipart/form-data、text/plain
瀏覽器對簡單請求與非簡單請求的處理,是不一樣的。
簡單請求
分析簡單請求:
對於簡單請求,瀏覽器直接發出CORS請求,具體來說就是在頭信息中增加一個Origin字段

解決問題:
后端服務器47.94.149.143 nginx允許跨域,nginx配置增加
add_header Access-Control-Allow-Origin *;
[root@master1 webapp]# cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/host.access_localhost.log main;
add_header Access-Control-Allow-Origin *;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
location ~* \.(gif|jpg|jpeg|js)$ {
root /static;
}
}

非簡單請求
瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求
如有在post請求時會多出一次附加的請求OPTIONS
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials true;
add_header 'Access-Control-Allow-Headers' "Referer,resourceId,sid,Sec-Fetch-Dest,Timestamp,Signature,Request-Id,userId,DNT,web-token,app-token,Authoriz
ation,Accept,Origin,Keep-Alive,User-Agent,x-user-agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header 'Access-Control-Expose-Headers' 'X-Log,X-Reqid';
add_header Access-Control-Request-Headers Origin,X-Requested-With,content-Type,Accept,Authorization;
add_header Access-Control-Max-Age 1728000;
return 200;
}
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' '1000' always;
add_header 'Access-Control-Allow-Methods' "POST, GET, OPTIONS, DELETE, PUT" always;
add_header 'Access-Control-Allow-Headers' "Referer,resourceId,sid,Sec-Fetch-Dest,Timestamp,Signature,Request-Id,userId,DNT,web-token,app-token,Authorization,Ac
cept,Origin,Keep-Alive,User-Agent,x-user-agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header 'Access-Control-Expose-Headers' 'X-Log,X-Reqid';
備注:Access-Control-Allow-Headers允許字段需開發提供,一起聯調設置
Access-Control-Allow-Origin允許的域名可以是*,也可以具體
如
set $cors_origin "";
if ($http_origin ~* "^http://base.hjq.komect.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https://base.hjq.komect.com$") {
set $cors_origin $http_origin;
}
add_header 'Access-Control-Allow-Origin' $cors_origin always;
