【Nginx】在Windows下使用Nginx解決前端跨域問題


提出問題:因為一些歷史原因,后台代碼不能動。請求別人的接口拿數據顯示在前端,怎么辦呢?

分析問題:通過ajax請求。

解決問題:因為瀏覽器的同源策略,所以需要解決跨域問題。(同源策略:請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名、端口、協議相同。)

 

帶着問題出發:使用Nginx做反向代理解決跨域問題

1、Nginx下載

   地址:http://nginx.org/en/download.html

   Nginx中文網:http://www.nginx.cn/doc/

 

 

2、下載完解壓之后的文件目錄

3、使用Notpad++打開conf文件夾下的nginx.conf配置文件並修改,主要修改http的server節點下

 server{
    # 設置本機監聽的端口
    listen       3868;
    # 設置本機ip
    server_name  localhost;
    client_max_body_size 20m;
    location / {
        root   html;
        index  index.html index.htm;
        client_max_body_size 20m;
    }
# 匹配到/apis開頭的接口時,轉發到下面的服務器地址 location /apis { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' *; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' *; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } # 匹配apis之后的路徑和參數 rewrite ^.+apis/?(.*)$ /$1 break; include uwsgi_params; # 實際調用的API proxy_pass http://4.103.63.13:8080; }

 

HTTPS的下載Nginx對應的證書

 

 

  # HTTPS server
   server {
    listen 443; # 監聽的端口號
    server_name https://pl.com;            # 服務器名稱
    client_max_body_size 100m;                     # 定義讀取客戶端請求大小
    ssl on;
    ssl_certificate test.pem;                      #配置證書位置
    ssl_certificate_key test.key;                  #配置秘鑰位置
    ssl_session_timeout 5m;
    ssl_protocols SSLv3 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM; 
    ssl_prefer_server_ciphers on;
    location / {
        root html; # 靜態資源目錄
        index index.html index.htm;
    }
    location /api {
            proxy_pass https://4:8080; # 設置代理服務器的協議和地址
            proxy_cookie_domain b.test.com  a.test.com; # 修改cookie,針對request和response互相寫入cookie
    }   
}

 

4、修改完成后保存,雙擊nginx.exe運行 或者命令行:nginx.exe

如果修改了配置文件可以命令行執行:nginx -s reload 重新加載

nginx -s reload # 重新載入配置文件 nginx -s reopen # 重啟 Nginx nginx -s stop # 停止 Nginx

 

5、地址欄輸入配置的端口和servername,檢查是否啟動

 也可在任務管理器中查看:

 

6、ajax調用

(1) GET:這樣實際請求的url是:http://4.103.63.13:8080/Service/getStations/3

  $.ajax({
        url: "http://localhost:3868/apis/Service/getStations/3",
        type: "GET",
        success: function(res) {
            alert(res.code);
        }
    });

 

(2) POST:如果是Ajax跨域ContentType為application/json請求時,注意使用JSON.stringify轉一下

   var params = {
        Name : "string",
        stationNo: "string"
    };
  
    $.ajax({
        url: "http://localhost:3868/apis/Service/setInfo",
        type: "POST",
        data: JSON.stringify(params),
        contentType: 'application/json',
        success: function(res) {
            alert(res.code);
        }
    });

 

(3) 擴展

http://jquery.cuishifeng.cn/jQuery.Ajax.html

使用Ajax跨域請求時,如果設置Header的ContentType為application/json,會分兩次發送請求。第一次先發送Method為OPTIONS的請求到服務器,這個請求會詢問服務器支持哪些請求方法(GET,POST等),支持哪些請求頭等等服務器的支持情況。等到這個請求返回后,如果原來我們准備發送的請求符合服務器的規則,那么才會繼續發送第二個請求,否則會在Console中報錯。

為什么在跨域的時候設置ContentType為application/json時會請求兩次?其實JQuery的文檔對此有做說明。

contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')

Type: Boolean or String

When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header. Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.

注意Note后面的描述,在跨域的時候,除了contentType為application/x-www-form-urlencoded,multipart/form-data或者text/plain外,都會觸發瀏覽器先發送方法為OPTIONS的請求。

比如說,你原來的請求是方法方法POST,如果第一個請求返回的結果Header中的Allow屬性並沒有POST方法,那么第二個請求是不會發送的,此時瀏覽器控制台會報錯,告訴你POST方法並不被服務器支持。

 

做到這里可以說完美解決了,但是前面說了是歷史原因,肯定要在IE8上試試,啥反應都沒有

在js里加上這段話即可~

jQuery.support.cors = true;

這句話的意思就是指定瀏覽器支持跨域。IE9以上版本的瀏覽器、谷歌、火狐等都默認支持跨域,而IE8、9卻默認不支持跨域,需要我們指定一下。

 

注意:接口API和Nginx只能一處配置跨域,如果API后台配置了允許跨域請求,Nginx就不能配置跨域了,不然會報錯:but only one is allowed. Origin 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM