Ajax跨域二(在浏览器、jsonp方面解决跨域)

一、在浏览器方面解决跨域:

浏览器的跨域设置,在浏览器的属性设置页面的目标输入框里加上--disable-web-security,这样就可以让浏览器支持跨域了

在浏览器的安装目录启动终端,输入禁止浏览器做跨域检查的校验参数,新启一个浏览器。

命令参数(参数视具体情况而定):chrome --disable-web-security --user-data-dir=g:\temp3

 

 二:JSONP解决跨域:

  对于发出XHR请求解决方案是JSONP

  JSONP如果解决跨域思路:利用script标签,请求可以跨域来解决跨域问题。

  办法:使用ajax发送请求,dataTypeJSONP,即可解决跨域问题。但这需要接口返回一个script标签如果返回其他格式的数据,浏览器将会把它当成是js代码解析,所以将会报错。(注意:此种情况也是需要修改服务器后台代码的)

 前端测试代码:

    // 测试方法
    it("jsonp请求", function(done) {
        // 服务器返回的结果
        var result; //初始化是undifined
        $.ajax({
            url:base+"/get1",
            dataType:"jsonp",    //关键数据类型:jsonp
            cache:true,  //加入缓存
            success:function(json){
                result = json;
            }
        });
        
        // 由于是异步请求,需要使用setTimeout来校验
        setTimeout(function() {
            expect(result).toEqual({
                "data" : "get1 ok"
            });

            // 校验完成,通知jasmine框架
            done();
        }, 100);
    });

直接调用会报跨域问题,如下:

可以看出jsonp在没有加后台代码情况下是会报错的,解决办法:添加一个后台代码(添加一个切面)

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{
    public JsonpAdvice(){
        super("callback");  //作用,前端调用的JSONP格式的时候,需要加上callback参数
    }
}

后台代码修改为JSONP后,在浏览器看到的区别

  1. 前端发出去的请求类型在浏览器可以看到是script类型的,浏览器是不会校验的。普通的ajax请求是xhr类型的。
  2. 返回的类型不同:普通的ajax请求content-type是json,而jsonp的请求content-type是js脚本。
  3. url不同,jsonp的url后面有callback...一串的参数。

 界面如下所示(加入后台代码之后,使用jsonp方式发送已不报错):

 

  jsonp是一种非正式传输协议,是前后台约定的协议,而不是官方协议。

jsonp的实现原理是:

  前后台约定带有“callback”这个参数的请求就是jsonp请求,前台发出去的请求加了“callback”参数,当后台发现请求中带“callback”时,后台就知道这是一个jsonp请求,就会把返回的数据由json变成JS代码返回,JS代码内容就是一个函数的调用,函数名是“callback”参数的值,而原来需要返回的json对象数据在这里作为参数传递返回。

 

补充说明:

1当把地址栏的“callback”改为“callback2”,点击浏览器控制台下的请求地址可以看到返回结果变成了json。原因是前后台约定的jsonp参数是“callback”,如果要正确返回jsonp的js代码,那么就需要后台参数改为“callback2”,前台的ajax请求里加jsonp:"callback2"参数设置。

2在浏览器查看jsonp请求里除了callback参数外,还有一个名为下划线“_”的参数,值为一串随机数。此参数作用是防止请求被缓存。如果你的请求可以被缓存的话,可以在请求里使用cache:true

 JSONP的弊端:

1服务器需要改动代码支持-如果调用的接口不是我们自己的,那么改动就很麻烦

2只支持GET方法JSONP是通过动态创建一个script发送请求的,而script只支持GET方法

3发送的不是XHR请求XHR有许多新的特性,如异步、各种事件等,JSONP则没有

 解决方案:

被调用方解决:是基于支持跨域的解决思路,基于http协议关于跨域方面的一些规定,在响应头里加允许调用字段,跨域请求是直接从浏览器发送过去的;

  (1)服务器端实现;(2NGINX配置;(3)APACHE配置。

 调用方解决:是基于隐藏跨域的解决思路,跨域请求不会直接从浏览器发到被调用方,而是从中间的http服务器转发过去的。

  举例子:调用方为a.com,被调用方为b.com。

 补充:跨域请求都是先请求后判断,就是先请求后台服务器返回内容,然后判断请求头是否存在跨域问题

理论参考:http://www.cnblogs.com/lojun/articles/9426409.html

代码下载地址:https://download.csdn.net/download/lowi313804/10584874

posted @ 2018-08-05 17:17  小码农成长记  阅读(103)  评论(0)    收藏  举报