Use nginx's reverse proxy mechanism to solve front-end cross-domain problems

https://www.cnblogs.com/gabrielchen/p/5066120.html

 

1. What is cross-domain and why

  Cross-domain means that page a wants to obtain page b resources. If the protocol, domain name, port, and subdomain name of page a and page b are different, or page a is an ip address and page b is a domain name address, the access actions performed are cross-domain. For security reasons, browsers generally restrict cross-domain access, that is, cross-domain requests for resources are not allowed.

  The cross-domain situation is as follows:

 

url illustrate Is it cross-domain
http://www.cnblogs.com/a.js
http://www.a.com/b.js
different domain names Yes
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
Different folders under the same domain name no
http://www.a.com:8000/a.js
http://www.a.com/b.js
Same domain name, different port Yes
http://www.a.com/a.js
https://www.a.com/b.js
Same domain name, different protocol Yes
http://www.a.com/a.js
http://70.32.92.74/b.js
Domain name and domain name corresponding to ip Yes
http://www.a.com/a.js
http://script.a.com/b.js
The main domain is the same, the subdomains are different Yes (cookie not accessible)
http://www.a.com/a.js
http://a.com/b.js
The same domain name, different second-level domain names (same as above) Yes

 

2. Common solutions across domains

At present, there is no technology that does not rely on the server to request resources across domains

  1.jsonp requires the target server to cooperate with a callback function.

  2.window.name+iframe requires the target server to respond to window.name.

  3.window.location.hash+iframe also needs to be processed by the target server.

  4.html5's postMessage+ifrme This also requires the target server or the target page to write a postMessage, mainly focusing on front-end communication.

  5. CORS   requires the server to set the header:Access-Control-Allow-Origin。

  6. The method of nginx reverse proxy  is rarely mentioned, but it can be used without the cooperation of the target server, but you need to build a transit nginx server to forward requests.

3.nginx reverse proxy to solve cross-domain

  As mentioned above, prohibiting cross-domain issues is actually a security behavior of browsers, and most of the current solutions use this vulnerability or trick that tags can be accessed across domains to complete, but the target server is indispensable for corresponding I recently encountered a requirement that the target server cannot give me a header, let alone change the code to return a script, so the first 5 solutions were rejected by me. Finally, because my website is my own host, I decided to build an nginx and deploy the corresponding code under it, request an address of this domain name from the page, transfer it to the nginx proxy and return the result to the page, and all this are all synchronous.

 

For some basic configuration and installation  of nginx, please see my other blog. The following directly explains how to configure a reverse proxy.

 

  First find nginx.conf or nginx.conf.default or this part in default   

          

   Among them, server represents a started service, and location is a positioning rule.

location /{ #All addresses starting with / are actually all requests

root html # To request the files in the ../html folder, the path of .. is defined in nginx, and there will be a default path during installation, see another blog for details

index  index.html index.htm  #首页响应地址

  

  从上面可以看出location是nginx用来路由的入口,所以我们接下来要在location里面完成我们的反向代理。

  假如我们我们是www.a.com/html/msg.html 想请求www.b.com/api/?method=1&para=2;

  我们的ajax:

var url = 'http://www.b.com/api/msg?method=1&para=2';

$.ajax({ type: "GET", url:url, success: function(res){..}, .... })

  

  上面的请求必然会遇到跨域问题,这时我们需要修改一下我们的请求url,让请求发在nginx的一个url下。

var url = 'http://www.b.com/api/msg?method=1&para=2'; 
var proxyurl = 'msg?method=1&para=2';
//假如实际地址是 www.c.com/proxy/html/api/msg?method=1&para=2; www.c.com是nginx主机地址
 $.ajax({ 
type: "GET", 
url:proxyurl, 
success: function(res){..}, 
.... 
})  

  

  

  再在刚才的路径中匹配到这个请求,我们在location下面再添加一个location。

location ^~/proxy/html/{
rewrite ^/proxy/html/(.*)$ /$1 break;
proxy_pass http://www.b.com/;
}

以下做一个解释

1.'^~ /proxy/html/ '

  就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。

2.rewrite ^/proxy/html/(.*)$ /$1 break;

  代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1&para=2重写。只对/proxy/html/api/msg重写。

  rewrite后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。

  break代表匹配一个之后停止匹配。

3.proxy_pass

  既是把请求代理到其他主机,其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下:

不带/

 location /html/
{
  proxy_pass http://b.com:8300;  
}

带/

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代理就成功了。

 

 

 

参考:http://seanlook.com/2015/05/17/nginx-location-rewrite/

         http://www.jbxue.com/article/2187.html

 

server { 
listen       80; 
server_name  A.ABC.com; 
location / { 
proxy_pass http://localhost:1234; 
proxy_set_header   Host    $host; 
proxy_set_header   X-Real-IP   $remote_addr; 
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 
} 

另外一个:

server { 
listen       80; 
server_name  B.ABC.com; 
location / { 
proxy_pass http://localhost:4321; 
proxy_set_header   Host    $host; 
proxy_set_header   X-Real-IP   $remote_addr; 
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 
} 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326218016&siteId=291194637