• 使用nginx实现浏览器跨域请求


    跨域访问问题, 相信很多人都遇到过, 并且都用不同的办法去解决过. 方法有很多种, 不一一叙述了. 这里主要使用nginx反向代理来解决跨域问题。

    啥是跨域?

    假如你是百度开发人员, 在百度页面去请求谷歌的资源, 算不算跨域?
    跨域是指一个域名的网页去请求另一个域名的资源. 只要协议, 域名, 端口中, 有任何一个不同, 都是跨域.
    谁限制了我们跨域?

    罪魁祸首, 是浏览器. 为了安全考虑. 如果一个网站可以随意的访问另一个网站的资源, 那么就有可能在客户不知情的情况下, 出现安全问题.
    比如:
    1. 用户访问淘宝, 进行了付钱操作, 这时cookie都生成, 存放在浏览器端.
    2. 付完钱后, 小伙去看了看苍老师(虽然她要结婚了, 但是不影响嘛)
    3. 这时候, 看苍老师的网站, 拿到了淘宝的cookie, 那是否可以替他买东西呢?
    4. 如果浏览器不限制, 且淘宝也没有做相应的安全处理, 那么还是有可能替他消费的.
    为啥要跨域?
    前端时间, 公司.net 项目的成员找到我们, 说想访问我们的资源, 希望我们修改配置, 支持他们跨域访问. 那不能拒绝啊, 都是为了工作嘛(主要是没有拒绝的权利嘛)。即使是同一家公司, 都会出现跨域访问的问题, 那我能不让他访问我这边的资源吗? 很明显, 做不到嘛, 那不还是要跨域!

    Ok, 前面说了那么多, 该进入主题了. 今天就用nginx来实现跨域访问, 消除 服务提供者的配置操作.

    一. 重现跨域问题

    新建两个项目, 一个用来提供数据, 一个用来访问数据

    server: 提供数据, 8081端口

    建一个项目 : server, 在其中加入一个控制器, 提供数据
    我只贴一些主要代码了.

    @RestController
    @RequestMapping("data")
    public class DataController {
        @RequestMapping("get")
        public List<Book> get(){
            List<Book> list = new ArrayList<>();
            list.add(new Book("海底两万里", 3000L));
            list.add(new Book("三体", 1000L));
            list.add(new Book("大鲸鱼", 2000L));
            list.add(new Book("是什么限制了我们的想象力", 4000L));
            return list;
        }
    }

    client: 访问数据, 8082端口

    <html>
    <body>
    <h2>Hello World! client</h2>
    <script src="js/jquery-1.9.1.js"></script>
    <script>
        $(function () {
            console.log("ajax start ...");
            $.ajax({
                url:'http://localhost:8081/server/data/get',
                type:'get',
                success:function (data) {
                    console.log(data);
                },
                error:function (data) {
                  console.log(data);
                }
            });
        });
    </script>
    </body>
    </html>

    发布到本地tomcat中

    1. 将webapps拷贝两份, 分别命名为 webappsclient, webappsserver

    将发布获取到的解压文件夹, 分别放进去.

    2. 修改tomcat配置文件,在server.xml文件中, 加入两个节点

    <Service name="Catalina1">  
        <Connector port="8081" maxHttpHeaderSize="8192"  
                   maxThreads="150" minSpareThreads="25" maxSpareThreads="75"  
                   enableLookups="false" redirectPort="8443" acceptCount="100"  
                   connectionTimeout="20000" disableUploadTimeout="true" /> 
        <Connector port="8009"  enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />  
        <Engine name="Catalina1" defaultHost="localhost">    
          <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>  
          <Host name="localhost" appBase="webappsserver"  
             unpackWARs="true" autoDeploy="true"  
             xmlValidation="false" xmlNamespaceAware="false">                
          </Host>    
        </Engine>  
    </Service> 
    <Service name="Catalina2">  
        <Connector port="8082" maxHttpHeaderSize="8192"  
                   maxThreads="150" minSpareThreads="25" maxSpareThreads="75"  
                   enableLookups="false" redirectPort="8443" acceptCount="100"  
                   connectionTimeout="20000" disableUploadTimeout="true" />  
        <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />  
        <Engine name="Catalina2" defaultHost="localhost">    
          <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>  
          <Host name="localhost" appBase="webappsclient"
             unpackWARs="true" autoDeploy="true"  
             xmlValidation="false" xmlNamespaceAware="false">                
          </Host>
        </Engine>
    </Service> 

    3. 启动tomcat, 验证访问结果

     

    别急, 按下 f12 看看

    报错, 不给数据给我.

    二. 解决跨域问题

    1. 修改nginx配置文件, 反向代理这两个服务. 然后启动nginx服务

    server {
            listen       8081;
            server_name  localhost;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
            location / {
                proxy_pass http://10.10.21.11:8081;
                index  index.html index.htm;
            }
        }
        server {
            listen       8082;
            server_name  localhost;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
            location / {
                proxy_pass http://10.10.21.11:8082;
                index  index.html index.htm;
                proxy_redirect default;
            }
            location /apis{
                rewrite ^.+apis/?(.*)$ /$1 break;
                proxy_pass http://10.10.21.11:8081;
            }
        }

    2. 修改ajax访问地址, 别的不需要动

    3. 查看访问结果

    这里的ip是nginx服务器的ip

    这才是我需要的数据. 

    接下来看一下, 发送出去的请求是啥样的.

    从地址上看, 并没有访问别的地址资源, 那么浏览器, 就认为, 没有跨域, 是同源的. 事实上, nginx通过反向代理, 将请求转发给 8081 了. 就这么的, 骗过了浏览器.

  • 相关阅读:
    ajax传参后台接受遇到问题
    使用xUnit为.net core程序进行单元测试(上)
    流程图规范
    知乎上看到的一些生活道理
    Dos常用命令
    c# 操作word写入特殊字符
    vb程序安装时需要在客户端安装MSSOAP30.dll,但注册不上,请问怎么处理
    VB 调用 webservice 出现:WSDLReader:Loading of the WSDL file failed HRESULT=0×80040154: 没有注册类别 解决方案
    The type 'System.Object' is defined in an assembly that is not referenced
    数据库还原失败解决方法
  • 原文地址:https://www.cnblogs.com/xyhero/p/9343838.html
Copyright © 2020-2023  润新知