zoukankan      html  css  js  c++  java
  • 关于跨域问题的几种解决方案

    1.什么是跨域?

    跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

    例如:a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。注意:跨域限制访问,其实是浏览器的限制。理解这一点很重要!!!

    同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;

    跨域原因产生:在当前域名请求网站中,默认不允许通过ajax请求发送其他域名。

    解决方案:

    一.跨域问题:能够正常请求,但是没有办法获取到响应结果

      b工程中直接在ajax访问a工程servlet

     1 $(function(){
     2             $("#button").click(function () {
     3                 //获取到文本框的值
     4                 var username=$("#username").val();
     5                 //发送Ajax请求www.a.com的A工程
     6                 $.ajax({
     7                     url:"http://www.a.com:8080/projectA/AServlet?username="+username,
     8                     type:"GET",
     9                     success:function (result) {
    10                         alert(result);
    11                     },
    12                     error:function () {
    13                         alert('系统错误~')
    14                     }
    15                 });
    16             });
    17         });

    A工程中能正确接收值

     但是success回调函数会报错提示

    No 'Access-Control-Allow-Origin' header

     
            解决方案一:设置请求头,在请求的资源中设置Access-Control-Allow-Origin请求头

    //设置请求头
    1
    response.setHeader("Access-Control-Allow-Origin", "*");

      正常回调

    解决方案二:JSONP解决跨域问题

    普通的跨域访问问题,浏览器会进行拦截,凡是src属性的都不会拦截
    JSONP实现原理:动态加载<script>标签,利用src属性进行服务器资源的访问,但是只支持Get请求


                    1.在我们的Ajax请求当中,需要以JSONP方式请求(通过jquery手段,动态生成script)
            
                        jsonp:"代表的是前台传给后台,后台再传递给你    jsonpCallBack"
                    
                    2.在AJAX请求当中需要将返回的数据格式指定为jsonp
                        
                          dataType:"JSONP"

                    3.JSONP需要以Get请求发送 

            ?username=zhangsan
                   
                    4.后台需要做的事情:
                        1.正常接收数据        
                        
                        2.返回数据
                            
                            前台传递过来的jsonp需要原路返回

                            String jsonp=request.getParameter("jsonpCallBack");

                            需要将返回的数据转换为JSON   success
                            
                            response.getWirter.write(jsonp+"("+返回的数据+")");

    修改Ajax请求:

    $(function(){
                $("#button").click(function () {
                    //获取到文本框的值
                    var username=$("#username").val();
                    //发送Ajax请求www.a.com的A工程
                    $.ajax({
                        url:"http://www.a.com:8080/projectA/AServlet?username="+username,
                        type:"GET",
                        jsonp:"jsonpCallBack",      //回调函数
                        dataType:"JSONP",
                        success:function (result) {
                            alert(result);
                        },
                        error:function () {
                            alert('系统错误~')
                        }
                    });
                });
            });

    更改后台请求,需要将JSONP原路返回

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.接受数据
            String username=request.getParameter("username");
            System.out.println("接收的数据:"+username);
    
            //接受Ajax传递的数据
            String jsonpCallBack = request.getParameter("jsonpCallBack");
            System.out.println("jsonpCallBack:"+jsonpCallBack);
    
            String success = JSON.toJSONString("success");
            response.getWriter().write(jsonpCallBack+"("+success+")");
    
           
        }

    成功解决:

     

     解决方案三:使用HTTPClient解决:就是不通过浏览器发送请求

    B工程的页面发送的Ajax没有办法请求到A工程,因为浏览器会拦截,走后台,后台通过HTTPClient请求请求到A工程,获取到响应结果

    1.B工程的bindex.jsp页面请求到B工程的Servlet

    $(function(){
                $("#button").click(function () {
                    //获取到文本框的值
                    var username=$("#username").val();
                    //发送Ajax请求www.a.com的A工程
                    $.ajax({
                        url:"BServlet?username="+username,
                        type:"GET",
                        success:function (result) {
                            alert(result);
                        },
                        error:function () {
                            alert('系统错误~')
                        }
                    });
                });
            });

    2.B工程的BServlet去模拟HTTP请求到A工程

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //内部通过HTTPClient进行转发
            //构建一个连接
            CloseableHttpClient client = HttpClients.createDefault();
            //构建请求
            HttpGet get=new HttpGet("http://www.a.com:8080/projectA/AServlet?username="+request.getParameter("username"));
            //发送请求
            CloseableHttpResponse httpResponse = client.execute(get);
            //获取返回结果
            String result = EntityUtils.toString(httpResponse.getEntity());
            //将A工程响应结果给页面
            response.getWriter().write(result);
    
        }

    3.A工程处理请求

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                        //1.接受数据
                        String username=request.getParameter("username");
                        System.out.println("接受的数据:"+username);
    
                        //2.响应结果
                        response.getWriter().write("success");
                        
                    }

    成功解决:

  • 相关阅读:
    有什么好的自助报表工具?
    各家报表工具对国产系统的支持如何
    Jenkins构建触发器(定时构建项目)
    Windows10安装Tomcat8.5与jdk1.8.0_181(以及可能出现的问题的解决)
    uinttest断言assert
    python判断语句if
    python运算符
    selenium如何定位鼠标悬停才显示的按钮
    python列表、元组、字典
    python常用数据类型
  • 原文地址:https://www.cnblogs.com/chx9832/p/12268914.html
Copyright © 2011-2022 走看看