zoukankan      html  css  js  c++  java
  • ajax跨域问题处理

    这段时间面试 经常会问到这个问题。也就是说,如果你的前端想要获取其他域名下的数据,前端需要如何请求,后端需要如何设置。

    最常见的处理方式有两种

    方法一,在java代码中设置response.setHeader("Access-Control-Allow-Origin","*");即可解决ajax跨域的问题,其中星号代表允许全部请求

    $.ajax({       
               type: "post",
               url: "http://192.168.1.88/testAjaxJson",
               contentType: "application/json",
               dataType:  "json",
               success: function(){
             alert("request succeed");
           }
    });
    @Controller 
    public class TestController {         
        /** 
         * 使用普通json方式跨域请求 
         * @param response 
         */ 
        @RequestMapping(value="/testAjaxJson")  
        public void testAjaxJson(HttpServletResponse response){  
            try {  
                // 这里设置为任意域请求都能获取到数据
                response.setHeader("Access-Control-Allow-Origin","*"); 
                // 这里还可以设置接收方式,固定域 二者选其一
                response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
                response.setHeader("Access-Control-Allow-Method", "POST");
                response.setHeader("Access-Control-Allow-Origin", "http://192.168.1.88");
               
    response.getWriter().print(
    "{"id":1}"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } }

      在正式post之前,浏览器会先发出一个options请求(也叫preflight),同时header带上origin还有Access-Control-Request-*:**之类的头,服务器响应会返回相应的access-control-allow-origin,如果匹配,那么浏览器就会发送正式post,否则就会出现上述错误。这也解答了,跨域访问时,我们明明发送的post请求,失败的话,查看chrome network会发现是options方法的原因。

    这里的content-type不属于(application/x-www-form-urlencoded,multipart/form-data,text/plain)中的任何一种,所以是复杂请求。

           复杂请求   第一次是options请求,http options请求跟get、post、head等一样,都属于http的请求方法,options方法,用来获取服务器端某url支持的方法,response header中allow标志支持的方法 

          第二次才是真正的请求

    方法二,使用jsonp的方式请求数据,后端需返回js方法调用,返回的数据放在参数中

    function testJsonp(){
        $.ajax({
            url:"http://192.168.1.88/testAjaxJsonp",
            type:"GET",//必须是get请求
            dataType:"jsonp",//请求的数据类型
            jsonp:"callback",//请求类型是回调
            jsonpCallback:"callbackFunction",//数据请求成功时回调的方法
            data:{  
            },//请求的数据
            success:function(data){//执行完成返回的数据
                alert(data.id);//输出值是1
            }
        });
    }
    @Controller 
    public class TestController {  
        @RequestMapping(value="/testAjaxJsonp")  
        public void testAjaxJsonp(@RequestParam String callback,HttpServletResponse response){  
            try {  
           // 这里jsonp返回的数据是固定格式 文后有详细解释 response.getWriter().print(callback
    +"({"id":1})"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } }

    jsonp跨域的原理解析

      jsonp的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了.

      JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。

      jsonCallback 函数jsonp123(....): 是浏览器客户端注册的,获取跨域服务器上的json数据后,回调的函数

    Jsonp原理:

      首先在客户端注册一个callback (如:'jsoncallback'), 然后把callback的名字(如:jsonp123)传给服务器。注意:服务端得到callback的数值后,要用jsonp123(......)把将要输出的json内容包括起来,此时,服务器生成 json 数据才能被客户端正确接收。

      然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 'jsoncallback'的值 jsonp123

      最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

      客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数,
      传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json))里.(动态执行回调函数)

      可以说jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空间就是大量采用这种方式来实现跨域数据交换的) .JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患.

      注意,jquey是不支持post方式跨域的.

    希望总结可以帮助到大家

    Dear: by_adidas
  • 相关阅读:
    java操作生成jar包 和写入jar包
    jboss配置jndi连接池
    windows 域的LDAP查询相关举例
    LDAP error Code 及解决方法
    HDU 6417
    CF1299D Around the World
    codechef Chef and The Colored Grid
    Educational Codeforces Round 82 (Rated for Div. 2)
    CF1237F Balanced Domino Placements
    CF1254E Send Tree to Charlie
  • 原文地址:https://www.cnblogs.com/adidas1/p/9473036.html
Copyright © 2011-2022 走看看