windows下nginx 配置代理 解決瀏覽器跨域訪問
1、首先我們要了解什麼是跨域訪問
什麼是跨域?
跨域,指的是瀏覽器不能執行其他網站的指令碼。它是由瀏覽器的同源策略造成的,是瀏覽器對javascript施加的安全限制。
所謂同源是指,域名,協議,埠均相同,不明白沒關係,舉個栗子:
url | 說明 | 是否跨域 |
http://www.cnblogs.com/a.js http://www.a.com/b.js |
不同域名 | 是 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不同資料夾 | 否 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不同埠 | 是 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不同協議 | 是 |
http://www.a.com/a.js http://70.32.92.74/b.js |
域名和域名對應ip | 是 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不同 | 是(cookie不可訪問) |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二級域名(同上) | 是 |
請注意:localhost和127.0.0.1雖然都指向本機,但也屬於跨域。
瀏覽器執行javascript指令碼時,會檢查這個指令碼屬於哪個頁面,如果不是同源頁面,就不會被執行。
XMLHttpRequest cannot load https://www.baidu.com/api/app/log/login. Redirect from 'https://www.baidu.com/api/app/log/login' to 'https://www.baidu.com/search/error.html'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
2、跨域的常見解決方法
1.jsonp 需要目標伺服器配合一個callback函式。
2.window.name+iframe 需要目標伺服器響應window.name。
3.window.location.hash+iframe 同樣需要目標伺服器作處理。
4.html5的 postMessage+ifrme 這個也是需要目標伺服器或者說是目標頁面寫一個postMessage,主要側重於前端通訊。
5.CORS 需要伺服器設定header :Access-Control-Allow-Origin。
6.nginx反向代理 這個方法一般很少有人提及,但是他可以不用目標伺服器配合,不過需要你搭建一箇中轉nginx伺服器,用於轉發請求。
其中1-5都需要服務端和客戶端配合才可以,6.只需要客戶端下載nginx伺服器,配置即可訪問
3、此篇文章使用nginx 反向代理來解決跨域問題nginx 的安裝和下載請參考其他文章,本文章不提及
1)、nginx 命令
nginx -s stop 關閉伺服器
nginx -t 檢視配置是否有明顯錯誤
nginx -s reload 重啟服務
2)最簡單的配置
nginx-1.12.2\conf
server {
listen 8020;
server_name 127.0.0.1;
#charset koi8-r;
#access_log logs/host.access.log main;
location /phone/ {
rewrite ^.+phone/?(.*)$ /$1 break;
proxy_pass http://99.99.99.99:8082;
}
location / {
root D:\git;
#index index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
本地頁面,使用
$.ajax({
type:"POST",
url: "127.0.0.1:8020/phone/api/log/checklog",
dataType: "json",
data: {
},
本地訪問 127.0.0.1:8020/phone/api/log/checklog
被nginx 代理後實際訪問: 99.99.99.99:8082/phone/api/log/checklog
這樣即可實現解決跨域問題
可理解為 將99.99.99.99/phone/的所有資源 搬到 127.0.0.1:8020/phone 下面
其中本地頁面放在
nginx.conf 12-15行 配置
D:\git; // 設定為location /的訪問路徑,當訪問路徑不帶/phone 時,到D盤下找資源
http://127.0.0.1:8020/mobileGroup/portal/login.html //就可去D:\git 下訪問
4 、引用
以下做一個解釋:
1.'^~ /proxy/html/ '
就像上面說的一樣是一個匹配規則,用於攔截請求,匹配任何以 /proxy/html/開頭的地址,匹配符合以後,停止往下搜尋正則。
2.rewrite ^/proxy/html/(.*)$ /$1 break;
代表重寫攔截進來的請求,並且只能對域名後邊的除去傳遞的引數外的字串起作用,例如www.c.com/proxy/html/api/msg?method=1¶=2重寫。只對/proxy/html/api/msg重寫。
rewrite後面的引數是一個簡單的正則 ^/proxy/html/(.*)$ ,$1代表正則中的第一個(),$2代表第二個()的值,以此類推。
break代表匹配一個之後停止匹配。
3.proxy_pass
既是把請求代理到其他主機,其中 http://www.b.com/ 寫法和 http://www.b.com寫法的區別如下:
不帶/
1 2 3 4 |
location
/html/
{
proxy_pass
http: //b.com:8300;
}
|
帶/
1 2 3 4 |
location
/html/
{
proxy_pass
http: //b.com:8300/;
}
|
上面兩種配置,區別只在於proxy_pass轉發的路徑後是否帶 “/”。
針對情況1,如果訪問url = http://server/html/test.jsp,則被nginx代理後,請求路徑會便問http://proxy_pass/html/test.jsp,將test/ 作為根路徑,請求test/路徑下的資源。
針對情況2,如果訪問url = http://server/html/test.jsp,則被nginx代理後,請求路徑會變為 http://proxy_pass/test.jsp,直接訪問server的根資源。
修改配置後重啟nginx代理就成功了。