Fork me on GitHub

【Distributed】网站跨域解决方案

一、概述

1.1 什么是网站跨域

  • 跨域原因产生:在当前域名请求网站中,默认不允许通过ajax请求发送其他域名。
  • 浏览器跨域问题产生的原因,如果使用ajax请求调用第三方接口,如果ajax访问的接口域名和端口号与浏览器访问的域名和端口号不一致的情况下,就会产生跨域问题。(属于浏览器安全策略)跨域不属于前端问题一定要端口号和域名一定要保持一致。

1.2 网站跨域报错案例

二、五种网站跨域解决方案

  1. 使用jsonp解决网站跨域
  2. 使用HttpClient内部转发
  3. 使用设置响应头允许跨域
  4. 基于Nginx搭建企业级API接口网关
  5. 使用Zuul搭建微服务API接口网关

三、使用JSONP解决网站跨域[1]

3.1 前端代码

 <script type="text/javascript">
        $(document).ready(function() {
        $.ajax({
            type : "GET",
            async : false,
            url : "http://127.0.0.1:8081/ajaxJsonpB",
            dataType : "jsonp",
            jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数 
            success : function(data) {
                alert(data["errorCode"]);
            },
            error : function() {
                alert('fail');
            }
        });

    });
    </script>

3.2 后端代码

@RequestMapping(value = "/ajaxJsonpB", method = RequestMethod.GET)
    public void ajaxB(HttpServletResponse response, String jsonpCallback) throws IOException {
        JSONObject root = new JSONObject();
        root.put("errorCode", "200");
        root.put("errorMsg", "登陆成功");
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.print(jsonpCallback + "(" + root.toString() + ")");
        writer.close();
}

  缺点:不支持post请求,代码书写比较复杂

四、使用设置响应头允许跨域[2]

4.1 前端代码

<script type="text/javascript">
    $(document).ready(function() {
        $.ajax({
            type : "GET",
            async : false,
            url : "http://127.0.0.1:8081/ajaxB",
            dataType : "json",
            success : function(data) {
                alert(data["errorCode"]);
            },
            error : function() {
                alert('fail');
            }
        });
    
    });
</script>

4.2 后端代码

@RequestMapping("/ajaxB")
    public Map<String, Object> ajaxB(HttpServletResponse response) {
        //告诉浏览器可以跨域 * 代表所有域名都可以跨域 正常将这个代码应该放在过滤器中
     response.setHeader("Access-Control-Allow-Origin", "*");
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("errorCode", "200");
        result.put("errorMsg", "登陆成功");
        return result;
}

设置响应头允许跨域,如果在实际项目中,该代码建议放在过滤器中。

五、使用HttpClient进行内部转发[3]

5.1 前端代码

<script type="text/javascript">
    $(document).ready(function() {
        $.ajax({
            type : "POST",
            async : false,
            url : "http://127.0.0.1:8080/forwardB",
            dataType : "json",
            success : function(data) {
                alert(data["errorCode"]);
            },
            error : function() {
                alert('fail');
            }
        });
    });
</script>

5.2 后端代码

// A项目进行转发到B项目    
@RequestMapping("/forwardB")
@ResponseBody
public JSONObject forwardB() {
    JSONObject result = HttpClientUtils.httpGet("http://127.0.0.1:8081/ajaxB");
    System.out.println("result:" + result);
    return result;
}
    
// B项目代码
    
@RequestMapping("/ajaxB")
public Map<String, Object> ajaxB(HttpServletResponse response) {
    Map<String, Object> result = new HashMap<String, Object>();
    result.put("errorCode", "200");
    result.put("errorMsg", "登陆成功");
    return result;
}

六、使用Nginx搭建API接口网关[4]

6.1 Nginx相关配置

server {
    listen       80;
    server_name  127.0.0.1;
    #A项目
    location /a {
        proxy_pass   http://127.0.0.1:8080/;
        index  index.html index.htm;
    }
    #B项目
    location /b {
        proxy_pass   http://127.0.0.1:8081/;
        index  index.html index.htm;
    }
}

6.2 前端代码

<script type="text/javascript">
$(document).ready(function() {
    $.ajax({
        type : "POST",
        async : false,
        url : "http://127.0.0.1/b/ajaxB",
        dataType : "json",
        success : function(data) {
            alert(data["errorCode"]);
        },
        error : function() {
            alert('fail');
        }
    });  
});
</script>

6.3 后端代码

    @RequestMapping("/ajaxB")
    public Map<String, Object> ajaxB(HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("errorCode", "200");
        result.put("errorMsg", "登陆成功");
        return result;
    }

七、SpringCloud搭建API接口网关[5]

  使用SpringCloud Zuul搭建API接口网关

posted @ 2019-09-17 13:20  这个世界~  阅读(358)  评论(0编辑  收藏  举报