ajax请求出错_JSONP愉快解决跨域接口请求

c9f49afc0e89b09efb7f198851654283.png

平时我们在浏览器中请求不同域名的接口数据的时候,通常浏览器会在控制台报一个跨域异常,提示拒绝访问。这是因为受到了同源策略的影响。

同源策略是什么

同源策略是浏览器最核心也是最基本的安全功能,同源指的是两条 URL 在协议、域名和端口上都是相同的,一旦有其中一个条件是不同的,两者就是不同源。同源保证了两个同源的 URL 之间在浏览器上是可以相互访问资源和可以操作 DOM  的,不同源 URL 在浏览器上互相访问的时候,浏览器就会判断到不同源,就会出来制裁,拒绝访问。 注意同源策源就只是浏览器行为,两个不同服务器接口互相访问,还是可以正常响应的。

同源策略作用的地方

同源策略主要作用在 DOM、Web数据和网络三个层面上。

  1. DOM层面:
    同源策略限制了来自不同源的JavaScript脚本对不同源页面的DOM对象读和写操作。

  2. Web数据层面:
    同源策源限制了不同源的JavaScript脚本读取对不同源页面的Cookie、LocalStorage等数据。

  3. 网络层面:
    同源策略限制了通过XMLHttpRequest、Fetch API等方式将不同源的接口数据获取回来。

回到文章的开头内容,我们在浏览器上请求不同域名的接口数据的时候,就是主要被限制在网络层面的 XMLHttpRequest(简称 XHR )上,目前所有的现代浏览器都内置了一个 XHR 对象,这个对象可以在页面加载后从服务器上请求以及获取数据,而不会影响页面的正常行为。XHR 在 AJAX 异步编程上是很关键的功能点。我们该如何解决跨域问题呢?一般我们都是设置 CORS 跨域资源共享,来打破同源策略的限制,实现 web 页面成功访问不同源的接口数据。另外就是使用 JSONP  的方式来是实现跨域请求。两者在对比上,CORS 支持所有类型的 HTTP 请求,而 JSONP 只支持 GET 请求,显然 CORS 是更为强大的, 不过 JSONP 的优势在于支持老式浏览器,还可以向不支持 CORS 的网站请求数据。下面我们将重点研究 JSONP。

JSONP是什么

JSONP 即 JSON with Padding ,看上去和 JSON 很像,其实他就是 JSON 的一种使用模式, 可用于解决现代浏览器的跨域数据访问的问题。非常聪明的程序员发现  HTML 页面的 Script 标签是没有跨域限制的,可以从其他不同源的网站获取   JSON 数据,而这种方式就是 JSONP,是一种非官方的跨域方式。 用 JSONP 获取的数据也并不是 JSON 对象,而是任意的 JavaScript 对象,用 JavaScript 直译器执行而不是用 JSON 解析器解析。具体理解看以下的 JSONP 工作原理

JSONP工作原理

通过在页面创建 script 标签,里面的具体内容是注册一个函数名为随机生成的 callback 值在客户端,然后将一个 callback 参数名以及随机生成的值拼接在接口的 URL 后面,将其最终请求的 URL 放进 src 属性,接着插入到 head 标签里面等待执行。执行的时候,参数将传送给服务器的接口,接口响应会生成 JSON 数据,然后以JavaScript 语法的方式,生成一个 function 函数,函数名就是入参 callback 的值。最后将 JSON 数据以入参的方式,放置到函数中,这样就生成了一段 JavaScript 语法的代码返回给了客户端。浏览器上的客户端,script 标签对返回的函数动态解析,将返回的函数入参数据传入到了预先注册好的 callback 函数里面,此时就获取到想到获取的数据了,在函数里面做具体的操作了。

JSONP具体实现

JSONP 在前端目前的实现方式有两种,一种是通过纯js代码实现,另一种是JQuery 实现,下面演示 JQuery 版本。

前端代码:

$.ajax({
    type: "get",
    async: false,
    url: "http://xxx.com/demo",
    dataType: "jsonp",
    jsonp: "callback", //默认的请求参数名
    jsonpCallback:"abc", //命令jsonp回调函数名称,也可写成问号让名称随机生成
    success: function(json){
    alert('您看到的数据为: ' + json);
    },
    error: function(){
    alert('请求出错');
    }
});

服务器Java代码:

@GetMapping("/demo")
public String getData(String callback){    
    if( callback == null ){        
        throw new RuntimeException("callback值不能为空");    
    }    
    return new StringBuilder(callback).append("(").append("关注微信公众号:红橙呀").append(")").toString();
}
通过 JSONP 的方式,我们下次遇到跨域问题,也可以使用它实现愉快的跨域请求,早点下班了~

往期精彩文章:

做好第三方对接,早日涨工资!

几分钟看懂Base64编码原理

分享我的网站部署过程!

96aeacc4e279d14762f27c96f3e1f986.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值