Nginx反向代理处理跨域问题

Nginx反向代理处理跨域问题

 

最近在做项目的时候遇到了一个问题,A系统首页,需要使用IFrame嵌套B系统、C系统的相关页面,那么问题来了——跨域。虽然我们Java9以上框架都有SameOriginIframe(请求头中是否增加X-Frame-Options=SAMEORIGIN,默认1添加,设置为0不添加)、AllowIframeURL(允许其他域名的iframe嵌套页面的地址)、webxml中有跨域过滤器配置这些配置,然而结果并不是很乐观,简单的一个list页面是可以完美嵌套,但是多增加一些弹窗、子父页面交互、浏览器兼容性等,就不能友好的实现了。

一、什么是跨域以及产生原因

  跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

二、跨域的常见解决方法

² html5的 postMessage+ifrme

² 把项目放在同一个tomcat下

² nginx反向代理

三、项目实践

3.1 项目背景

系统: Cas + 统一支撑平台 + OA +其他业务子系统

   部署:

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反向代理

 

1、什么是Nginx

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、 腾讯,另外知名的微网志Plurk也使用nginx。

2、下载地址

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

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

 

3、Nginx配置

Nginx的配置文件是一个纯文本文件,它一般位于Nginx安装目录的conf目录下,整个配置文件是以block的形式组织的。每个block一般以一个大括号“{}”来表示,block可以分为几个层次,整个配置文件中Main指令位于最高层,在Main层下面可以有Events、HTTP等层级,而在HTTP层中又包含有Server层,即server block,server block中又可分为location层,并且一个server block中可以包含多个location block。

4、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

效果图:

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/panmy/p/8902747.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值