本文最后更新于:3 个月前
                  
                
              
            
            
              
                
                使用nginx解决跨域问题(前端解决)
情况是这样的:编写好的前端页面本地打开是没有问题的,请求都能发出去,接收到正确的响应结果。但是,使用nginx来部署这个页面就会出现跨域问题。
跨域:由于浏览器的同源策略,即属于不同域的页面之间不能相互访问各自的页面内容 注:同源策略,单说来就是同协议,同域名,同端口。
前端代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | <!DOCTYPE html><html>
 
 <head>
 <meta charset="utf-8">
 <script>
 function loadXMLDoc() {
 var xmlhttp;
 if (window.XMLHttpRequest) {
 
 xmlhttp = new XMLHttpRequest();
 }
 else {
 
 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange = function () {
 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
 document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
 }
 }
 xmlhttp.open("GET", "http://localhost:8888/mc/http/interface.ms?model=DeviceMaintainInfoSelectAll&method=DeviceMaintainInfoSelectAll", true);
 xmlhttp.send();
 }
 </script>
 </head>
 
 <body>
 
 <div id="myDiv">
 <h2>使用 AJAX 修改该文本内容</h2>
 </div>
 <button type="button" onclick="loadXMLDoc()">修改内容</button>
 
 </body>
 
 </html>
 
 | 
结果是:

nginx配置代理
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | # localhost/mc 的请求会被转发到localhost:8888location /mc {
 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,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
 add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
 
 proxy_pass http:
 }
 
 | 
但是仍然是跨域问题:

我们需要修改前端代码,将之前请求的ip地址+端口改成前端服务的ip地址+端口。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | <!DOCTYPE html><html>
 
 <head>
 <meta charset="utf-8">
 <script>
 function loadXMLDoc() {
 var xmlhttp;
 if (window.XMLHttpRequest) {
 
 xmlhttp = new XMLHttpRequest();
 }
 else {
 
 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange = function () {
 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
 document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
 }
 }
 xmlhttp.open("GET", "http://localhost:88/mc/http/interface.ms?model=DeviceMaintainInfoSelectAll&method=DeviceMaintainInfoSelectAll", true);
 xmlhttp.send();
 }
 </script>
 </head>
 
 <body>
 
 <div id="myDiv">
 <h2>使用 AJAX 修改该文本内容</h2>
 </div>
 <button type="button" onclick="loadXMLDoc()">修改内容</button>
 
 </body>
 
 </html>
 
 | 
在这里跨域问题本应该解决了,但是我这里出现了 403 (Forbidden)的报错

在nginx配置中添加proxy_set_header Host $http_host;后解决了问题。
不设置 proxy_set_header Host 时,浏览器直接访问 nginx,获取到的 Host 是 proxy_pass 后面的值,即 $proxy_host 的值
设置 proxy_set_header Host $host 时,浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息
设置 proxy_set_header Host $host:$proxy_port 时,浏览器直接访问 nginx,获取到的 Host 是 $host:$proxy_port 的值 
设置 proxy_set_header Host $http_host 时,浏览器直接访问 nginx,获取到的 Host 包含浏览器请求的 IP 和端口
设置 proxy_set_header Host $host 时,浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息。此时代码中如果有重定向路由,那么重定向时就会丢失端口信息,导致 404
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | # localhost/mc 的请求会被转发到localhost:8888location /mc {
 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,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
 add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
 
 proxy_pass http:
 proxy_set_header Host $http_host;
 }
 
 | 
成功请求到数据。

附(全部nginx配置):
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | worker_processes  1;
 events {
 worker_connections  1024;
 }
 
 
 http {
 include       mime.types;
 default_type  application/octet-stream;
 
 sendfile        on;
 
 
 
 keepalive_timeout  65;
 
 
 
 server {
 listen       88;
 server_name  localhost;
 
 location / {
 root   html;
 index  index.html index.htm;
 }
 
 
 location /mc {
 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,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
 add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
 
 proxy_pass http://localhost:8888;
 proxy_set_header Host $http_host;
 }
 
 
 error_page   500 502 503 504  /50x.html;
 location = /50x.html {
 root   html;
 }
 }
 }
 
 
 |