跨域问题简单分析

Posted ywb-articles

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域问题简单分析相关的知识,希望对你有一定的参考价值。

一.什么是跨域问题

  一句话总结就是: 浏览器从一个域名的网页去请求另一个域名的资源时,子域名、主域名、端口、协议任一不同,都是跨域。

  如果不是特别指定,跨域问题包括 Ajax跨域请求资源问题,cookie跨域访问,session跨域共享等问题。

  举几个跨域的例子如下:

    https://www.abc.com/index.html 请求 http://www.abc.com/hello.html资源      协议不同,跨域。

    http://www.abc.com:8080/index.html 请求 http://www.abc.com:8088/hello.html 端口不同,跨域。

    http://www.abc.com/index.html 调用  http://www.xxx.com/hello.html       域名不同,跨域。

    http://localhost:8080/index.html 调用 http://127.0.0.1:8080/hello.html      就算localhost对应的ip就是127.0.0.1,但这也是跨域。(注意)

二.为什么会有跨域问题

  因为浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源 (浏览器的同源策略)

三.如何解决跨域问题

  1.解决跨域问题的一些方案

    a.通过 jsonp 的方式(缺陷是仅限于get方式的请求)

//前端修改ajax
$.ajax({ type:
"get", async:false, url:"http://localhost:8081/hello.html", dataType:"jsonp",//数据类型为jsonp jsonp:"backFunction",//服务端可以通过request获得jsonp的数据 success:function (data) { alert("success"); }, error:function () { alert("error"); } });
//后台设置
public
class MyServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { JSONObject jsonObject = new JSONObject(); String backFunction = req.getParameter("backFunction"); resp.getWriter().println(backFunction+"("+jsonObject.toJSONString()+")"); } }

    b.通过 jQuery的jsonp方法

      直接将ajax修改成jsonp方法,支持post等其他方式的请求,详情可参考官方文档

    c.通过HttpClient请求转发

      只需要在后台中设置即可(需要导入相关的依赖),例如:

    public static String doGet(String url, Map<String,String> param) {  
  
        // 创建Httpclient对象  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
  
        String resultString = "";  
        CloseableHttpResponse response = null;  
        try {  
            // 创建uri  
            URIBuilder builder = new URIBuilder(url);  
            if (param != null) {  
                for (String key : param.keySet()) {  
                    builder.addParameter(key, param.get(key));  
                }  
            }  
            URI uri = builder.build();  
  
            // 创建http GET请求  
            HttpGet httpGet = new HttpGet(uri);  
  
            // 执行请求  
            response = httpclient.execute(httpGet);  
            // 判断返回状态是否为200  
            if (response.getStatusLine().getStatusCode() == 200) {  
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if (response != null) {  
                    response.close();  
                }  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return resultString;  
    }  

    d.在response中添加header信息(也就是CORS方法)

      例如在doGet或doPost方法中添加

resp.setHeader("Access-Control-Allow-Origin", "*");//后面的*表示请求的方式

    e.通过nginx搭建企业接口网关

      只需在nginx的配置文件中配置即可(可以参考我的上一篇博客  https://www.cnblogs.com/ywb-articles/p/10686673.html  )

      例如在配置文件中设置,根据请求的路径跳转到不同的服务器中。也可以在nginx中使用CORS的方法,如下图所示

      技术图片

    f.使用Spring Cloud的ZULL接口网关

以上是关于跨域问题简单分析的主要内容,如果未能解决你的问题,请参考以下文章

浏览器跨域问题分析

谷歌分析跨域跟踪转化推荐问题

Nginx 跨域

怎样避免跨域发出OPTIONS请求?

为啥这段代码会泄露? (简单的代码片段)

Nginx 代理解决跨域问题分析