打赏

【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 

posted @ 2019-05-16 09:58  cksun  阅读(3343)  评论(0编辑  收藏  举报