Nginx反向代理處理跨域問題

Nginx反向代理處理跨域問題

 

最近在作項目的時候遇到了一個問題,A系統首頁,須要使用IFrame嵌套B系統、C系統的相關頁面,那麼問題來了——跨域。雖然咱們Java9以上框架都有SameOriginIframe(請求頭中是否增長X-Frame-Options=SAMEORIGIN,默認1添加,設置爲0不添加)、AllowIframeURL(容許其餘域名的iframe嵌套頁面的地址)、webxml中有跨域過濾器配置這些配置,然而結果並非很樂觀,簡單的一個list頁面是能夠完美嵌套,可是多增長一些彈窗、子父頁面交互、瀏覽器兼容性等,就不能友好的實現了。php

1、什麼是跨域以及產生緣由

  跨域是指a頁面想獲取b頁面資源,若是a、b頁面的協議、域名、端口、子域名不一樣,或是a頁面爲ip地址,b頁面爲域名地址,所進行的訪問行動都是跨域的,而瀏覽器爲了安全問題通常都限制了跨域訪問,也就是不容許跨域請求資源。html

2、跨域的常看法決方法

² html5的 postMessage+ifrmehtml5

² 把項目放在同一個tomcat下node

² nginx反向代理nginx

3、項目實踐

3.1 項目背景web

系統: Cas + 統一支撐平臺 + OA +其餘業務子系統正則表達式

   部署:windows

Cas+統一支撐平臺在同一個tomcat下,端口號:8208後端

OA單獨一個tomcat,端口號爲:8083跨域

其餘業務子系統若干個

問題:統一支撐平臺中須要作一個「個人桌面」頁面,頁面的內容須要根據不一樣的人員展現不一樣的頁面信息

3.2方法分解

3.2.1 使用postMessage+iframe

  這裏不過多解釋,能夠參考公司陳東順的技術論壇

http://oa2.epoint.com.cn/EpointCommunity/EpointCommunity/Dis/ShowTopic.aspx?TopicID=6646使用他的話解釋就是:A通知B,B該幹嗎了,B接收到通知後,對內容和來源肯定後,B本身調用本身的頁面方法,從而克服了跨域時,子父頁面任何js不能夠調用的問題。

  這確實是一個好方法,可是在項目的實際運用中,須要處理的細節太多,例如:參數、window對象、parent對象、頻繁通知等等,一個頁面還好而十幾個頁面那工做量就很大了

3.2.2 把項目放在同一個tomcat下

  假設如今須要引用OA系統的頁面,而後把Cas、統一支撐平臺、OA放在一同一隻Tomcat下。這樣會致使沒法啓動tomat,緣由:OA接入的了統一支撐平臺,OA在啓動tomcat的時候會先去獲取統一支撐平臺上的組織架構。因此,若是沒有這連帶關係此方案是最快處理跨域問題。

3.2.3 使用Nginx反向代理

 

一、什麼是Nginx

Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。其特色是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁伺服器中表現較好.目前中國大陸使用nginx網站用戶有:新浪、網易、 騰訊,另外知名的微網誌Plurk也使用nginx。

二、下載地址

官網:http://nginx.org/cn/

公司:http://fdoc.epoint.com.cn:3366/middleware/Nginx/Nginx_install_windows.html

 

三、Nginx配置

Nginx的配置文件是一個純文本文件,它通常位於Nginx安裝目錄的conf目錄下,整個配置文件是以block的形式組織的。每一個block通常以一個大括號「{}」來表示,block能夠分爲幾個層次,整個配置文件中Main指令位於最高層,在Main層下面能夠有Events、HTTP等層級,而在HTTP層中又包含有Server層,即server block,server block中又可分爲location層,而且一個server block中能夠包含多個location block。

四、nginx基礎知識

 

基礎知識
Nginx location 配置語法
    1. location [ = | ~ | ~* | ^~ ] uri { ... }
    2. location @name { ... }    
location 配置能夠有兩種配置方法
1.前綴 + uri(字符串/正則表達式)
2.@ + name
前綴含義
    =  :精確匹配(必須所有相等)
    ~  :大小寫敏感
    ~* :忽略大小寫
    ^~ :只需匹配uri部分
    @  :內部服務跳轉
Location 基礎知識
1.location 是在 server 塊中配置。
2.能夠根據不一樣的 URI 使用不一樣的配置(location 中配置),來處理不一樣的請求。
3.location 是有順序的,會被第一個匹配的location 處理。
Location 配置demo
1.=,精確匹配

        location = / {
            #規則
        }
        # 則匹配到 `http://www.example.com/` 這種請求。 
2.~,大小寫敏感

        location ~ /Example/ {
                #規則
        }
        #請求示例
        #http://www.example.com/Example/  [成功]
        #http://www.example.com/example/  [失敗]
3.~*,大小寫忽略

    location ~* /Example/ {
                #規則
    }
    # 則會忽略 uri 部分的大小寫
    #http://www.example.com/Example/  [成功]
    #http://www.example.com/example/  [成功]
4.^~,只匹配以 uri 開頭

    location ^~ /img/ {
            #規則
    }
    #以 /img/ 開頭的請求,都會匹配上
    #http://www.example.com/img/a.jpg   [成功]
    #http://www.example.com/img/b.mp4 [成功]
5.@,nginx內部跳轉

    location /img/ {
        error_page 404 @img_err;
    }
    
    location @img_err {
        # 規則
    }
    #以 /img/ 開頭的請求,若是連接的狀態爲 404。則會匹配到 @img_err 這條規則上。

關閉:
nginx -s quit
啓動
start nginx
從新載入
nginx.exe -s reload
檢查配置文件
nginx -t

  

nginx.conf的配置文件詳解以下:

 

#開啓進程數 <=CPU數 
worker_processes 1; 
   
#錯誤日誌保存位置 
#error_log logs/error.log; 
#error_log logs/error.log notice; 
#error_log logs/error.log info; 
   
#進程號保存文件 
#pid logs/nginx.pid; 
   
#等待事件 
events { 
#每一個進程最大鏈接數(最大鏈接=鏈接數x進程數)  
worker_connections 1024; 
} 
   
   
http { 
#文件擴展名與文件類型映射表 
include mime.types; 
   
#默認文件類型 
default_type application/octet-stream; 
   
#日誌文件輸出格式 這個位置相於全局設置 
#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 
# '$status $body_bytes_sent "$http_referer" ' 
# '"$http_user_agent" "$http_x_forwarded_for"'; 
   
#請求日誌保存位置 
#access_log logs/access.log main; 
   
#打開發送文件 
sendfile on; 
#tcp_nopush on; 
   
#鏈接超時時間 
#keepalive_timeout 0; 
keepalive_timeout 65; 
   
#打開gzip壓縮 
#gzip on; 
   
#設定請求緩衝 
client_header_buffer_size 1k; 
large_client_header_buffers 4 4k; 
   
#設定負載均衡的服務器列表 
upstream myproject {  
#weigth參數表示權值,權值越高被分配到的概率越大 
#max_fails 當有#max_fails個請求失敗,就表示後端的服務器不可用,默認爲1,將其設置爲0能夠關閉檢查 
#fail_timeout 在之後的#fail_timeout時間內nginx不會再把請求發往已檢查出標記爲不可用的服務器 
#這裏指定多個源服務器,ip:端口,80端口的話可寫可不寫  
server 192.168.1.78:8080 weight=5 max_fails=2 fail_timeout=600s; 
#server 192.168.1.222:8080 weight=3 max_fails=2 fail_timeout=600s;  
} 
   
#第一個虛擬主機 
server { 
#監聽IP端口 
listen 80; 
   
#主機名 
server_name localhost; 
   
#設置字符集 
#charset koi8-r; 
   
#本虛擬server的訪問日誌 至關於局部變量 
#access_log logs/host.access.log main;  
   
#對本server"/"啓用負載均衡 
location / {  
#root /root; #定義服務器的默認網站根目錄位置 
#index index.php index.html index.htm; #定義首頁索引文件的名稱 
proxy_pass http://myproject; #請求轉向myproject定義的服務器列表 
   
#如下是一些反向代理的配置可刪除. 
# proxy_redirect off;  #後端的Web服務器能夠經過X-Forwarded-For>獲取用戶真實IP
# proxy_set_header Host $host;  
# proxy_set_header X-Real-IP $remote_addr;  
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
# client_max_body_size 10m; #容許客戶端請求的最大單文件字節數  
# client_body_buffer_size 128k; #緩衝區代理緩衝用戶端請求的最大字節數,  
# proxy_connect_timeout 90; #nginx跟後端服務器鏈接超時時間(代理鏈接超時)  
# proxy_send_timeout 90; #後端服務器數據回傳時間(代理髮送超時)  
# proxy_read_timeout 90; #鏈接成功後,後端服務器響應時間(代理接收超時)  
# proxy_buffer_size 4k; #設置代理服務器(nginx)保存用戶頭信息的緩衝區大小  
# proxy_buffers 4 32k; #proxy_buffers緩衝區,網頁平均在32k如下的話,這樣設置  
# proxy_busy_buffers_size 64k; #高負荷下緩衝大小(proxy_buffers*2)  
# proxy_temp_file_write_size 64k; #設定緩存文件夾大小,大於這個值,將從upstream服務器傳 
}  
location /upload {  
alias e:/upload;  
} 
#設定查看Nginx狀態的地址  
location /NginxStatus {  
stub_status on;  
access_log off;  
#allow 192.168.0.3; 
#deny all; 
#auth_basic "NginxStatus";  
#auth_basic_user_file conf/htpasswd;  
} 
   
#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; 
#} 
}  
   
   
# another virtual host using mix of IP-, name-, and port-based configuration 
# 
#server { 
#多監聽  
# listen 8000; 
#主機名 
# listen somename:8080; 
# server_name somename alias another.alias; 
   
# location / { 
#WEB文件路徑 
# root html; 
#默認首頁 
# index index.html index.htm; 
# } 
#} 
   
   
# HTTPS server HTTPS SSL加密服務器 
# 
#server { 
# listen 443; 
# server_name localhost; 
   
# ssl on; 
# ssl_certificate cert.pem; 
# ssl_certificate_key cert.key; 
   
# ssl_session_timeout 5m; 
   
# ssl_protocols SSLv2 SSLv3 TLSv1; 
# ssl_ciphers HIGH:!aNULL:!MD5; 
# ssl_prefer_server_ciphers on; 
   
# location / { 
# root html; 
# index index.html index.htm; 
# } 
#}  
} 

  

Nginx 正則表達式:

~     區分大小寫(大小寫敏感)匹配成功 
~*   不區分大小寫匹配成功 
!~    區分大小寫匹配失敗 
!~*  不區分大小寫匹配失敗

^: 匹配字符串的開始位置;

$:匹配字符串的結束位置;

\. 斜槓用來轉義,\.匹配 .   

 

4、項目使用

配置以下:

 

 

#user  nginx;
worker_processes  auto;
daemon on;
error_log  logs/error.log;
pid        nginx.pid;
events {
    worker_connections  65535;
}
worker_rlimit_nofile 65535;

http {
    include       mime.types;
    default_type  application/octet-stream;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    #charset utf-8;
    log_format main '$time_local  $remote_addr  $request_method '
                  '$request_uri  $uri  $request_time '
                  '$status   $body_bytes_sent ' 
                  '$http_referer  $upstream_addr  $upstream_response_time ' 
                  '$http_user_agent  $http_x_forwarded_for  $content_length';

    access_log  logs/access.log  main;
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;
    gzip  on;
    server_tokens off;
    #----------------------------------

    upstream epoinOA9 {
        server 127.0.0.1:8083;
    } 
	upstream epoinAQZH {
        server 127.0.0.1:8208;
    }
	upstream epoincsa3 {
        server 127.0.0.1:8208;
    }
	upstream epoinMobile {
        server 127.0.0.1:8208;
    }  

	upstream epoinEMP7 {
        server 127.0.0.1:8208;
    }
    server {
        listen       8082;
        server_name  localhost; 
        client_max_body_size 64M;
        proxy_connect_timeout 75s; 
        proxy_read_timeout 60s; 
        proxy_send_timeout 60s;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location  ~ ^(.*)\/\.svn\/  {
            return 404;
        }
		
		location ~ /AQZHZJOA9 {
             rewrite ^/AQZHZJ(.*)$ /AQZHZJ_$1 break;
		}
		
		location ~ /AQZHZJ_OA9 {
			proxy_pass     http://epoinOA9;
			proxy_cookie_path  /AQZHZJ_OA9/ /;  
            proxy_set_header   Host    $host:$server_port;  
            proxy_set_header   X-Real-IP   $remote_addr;   
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;   			
		}
		location ~ /AQZHZJ {
			proxy_pass     http://epoinAQZH;
			proxy_cookie_path  /AQZHZJ/ /;  
            proxy_set_header   Host    $host:$server_port;  
            proxy_set_header   X-Real-IP   $remote_addr;   
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  			
		}
		location ~ /cas3 {
			proxy_pass     http://epoincsa3;
			proxy_cookie_path  /cas3/ /;  
            proxy_set_header   Host    $host:$server_port;  
            proxy_set_header   X-Real-IP   $remote_addr;   
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  			
			
		}
		location ~ /EpointMobilePlatform6 {
			proxy_pass     http://epoinMobile;
			proxy_cookie_path  /EpointMobilePlatform6/ /;  
            proxy_set_header   Host    $host:$server_port;  
            proxy_set_header   X-Real-IP   $remote_addr;   
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  			
			
		}
		location ~ /EMP7 {
			proxy_pass     http://epoinEMP7;
			proxy_cookie_path  /EMP7/ /;  
            proxy_set_header   Host    $host:$server_port;  
            proxy_set_header   X-Real-IP   $remote_addr;   
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  			
			
		}
		
		

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }


        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    #其餘server配置
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}



    #HTTPS server的支持
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

  

 

 

 

 

使用nginx主要是配置問題,

監聽IP端口:8082

主機名:localhost

反向代理了:8208,8083兩個端口

配置規則:AQZHZJ_OA9ZQZHZJ

效果圖:

 

 

相關文章
相關標籤/搜索