手机版

如何使用jquery通过jsonp发起跨域请求及其原理

时间:2021-09-03 来源:互联网 编辑:宝哥软件园 浏览:

本文主要介绍jquery jsonp发起跨域请求的相关内容及其原理,并分享给大家参考和学习。下面就不多说了,我们来看看详细的介绍:

跨域安全限制是针对浏览器端的,服务器端没有跨域安全限制。

浏览器的同源策略限制从一个源加载的文档或脚本与另一个源的资源进行交互。

如果两个页面的协议、端口和主机相同,则这两个页面具有相同的源,否则它们具有不同的源。

如果你想在js中发起一个跨域请求,你需要做一些特殊的处理。或者,您可以将请求发送到自己的服务器,通过后台代码发起请求,并将数据返回给前端。

下面是jsonp如何使用jquery发起跨域请求及其原理。

先看准备环境:两个端口不同,构成跨域请求的条件。

获取数据:获取数据的端口是9090

请求数据:请求数据的端口是8080

1.让我们首先看看当您直接启动ajax请求时会发生什么

以下是启动请求端的代码:

“%@”页面页面编码=“utf-8”内容类型=“文本/html;charset=utf-8 ' language=' Java ' % html head title跨域测试/title script src=' http : js/jquery-1 . 7 . 2 . js '/script script $(文档)。ready (function () {$ ('# btn '))。单击(function () { $)。Ajax({ URL : ' http://localhost :9090/student ',type: 'GET ',success:函数(数据){ $(文本)。val(数据);} });});});/script/head body输入id=' BTN' type=' button' value='跨域数据采集'/text area id=' text ' style=' width : 400 px;' height: 100px'/textarea/body/html请求的结果如下:可以看到由于浏览器的同源策略,跨域请求被拦截。

2.接下来,看看如何发起跨域请求。有许多方法可以解决跨域请求。这里我们只讨论jquery的jsop模式及其原理。

首先我们需要明白,页面上不可能直接发起跨域的ajax请求,但是可以在页面上引入来自不同域的js脚本,就像你可以在自己的页面上使用img src='http: '标签随意显示某个域的图片一样。

例如,我在端口8080的页面上请求了端口9090的图片:您可以看到通过src直接跨域请求是可以的。

3.然后看看如何使用脚本src='http: '来完成跨域请求:

单击“跨域获取数据”按钮时,添加用于发起跨域请求的脚本标记;请注意,请求地址后面是回调=showData参数;

ShowData是回调函数的名称,它被传递到后台用于包装数据。数据返回前端后,是showData(结果)的形式。因为是脚本脚本,所以自动调用showData函数,结果就是showData的参数。

此时,我们已经跨域返回了数据请求,但是很麻烦。我们需要自己编写脚本来发起请求,然后编写回调函数来处理数据,不是很方便。

“%@”页面页面编码=“utf-8”内容类型=“文本/html;charset=utf-8 ' language=' Java ' % html head title跨域测试/title script src=' http : js/jquery-1 . 7 . 2 . js '/script script//回调函数show data(result){ vardata=JSON . stringfy(result);//json对象转换为字符串$(“# text”)。val(数据);} $(文档)。ready (function () {$ ('# BTN '))。click(function(){//向head输入脚本,这会启动跨域请求$ ('head ')。追加(' script src=' http://localhost 33609090/student?callback=show data ' \/script ');});});/script/head body输入id=' BTN' type=' button' value='跨域数据采集'/text area id=' text ' style=' width : 400 px;' height: 100px'/textarea/body/html服务器:

受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)引发ServletException,IOException { response。setcharacter编码(' UTF-8 ');回应。setcontenttype(' text/html;字符集=UTF-8 ';//数据list学生学生列表=getstudent list();JSON数组JSON数组=JSON数组。来自对象(studentList);字符串结果=JSonarray。ToString();//前端传过来的回调函数名称字符串回调=request.getParameter('回调');//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了结果=回调(“结果”);response.getWriter().写(结果);}结果:

4、再来看jquery的jsonp方式跨域请求:

服务端代码不变,js代码如下:最简单的方式,只需配置一个dataType:'jsonp ',就可以发起一个跨域请求jsonp。指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个回调=xxx,xxx是jquery随机生成的一个回调函数名称。

这里的成功就跟上面的显示数据一样,如果有成功函数则默认成功()作为回调函数。

"%@"页面页面编码="utf-8 "内容类型="文本/html;charset=UTF-8 "语言="Java"% html标题跨域测试/title脚本src=' http : js/jquery-1。7 .2 .js '/script脚本$(文档)。ready(function () { $('#btn ')).单击(函数(){ $).Ajax({ URL : ' http://localhost :9090/student ',类型: 'GET ',数据类型: 'jsonp ',//指定服务器返回的数据类型成功:函数(数据){ var result=JSON.stringify(数据);//json对象转成字符串$('#text ').val(结果);} });});});/脚本/流浆池输入id='btn' type='button' value='跨域获取数据/text area id=' text ' style=' width : 400 px;height : 100px '/textarea/body/html效果:

再看看如何指定特定的回调函数:第30行代码

回调函数你可以写到脚本下(默认属于窗户对象),或者指明写到窗户对象里,看jquery源码,可以看到jsonp调用回调函数时,是调用的窗户。回调。

然后看调用结果,发现,请求时带的参数是:回调=显示数据调用回调函数的时候,先调用了指定的显示数据,然后再调用了成功。所以,成功是返回成功后必定会调用的函数,就看你怎么写了。

"%@"页面页面编码="utf-8 "内容类型="文本/html;charset=UTF-8 "语言="Java"% html标题跨域测试/title脚本src=' http : js/jquery-1。7 .2 .js /脚本脚本函数显示数据(数据){ console.info('调用显示数据’);var result=JSON.stringify(数据);$('#text ').val(结果);} $(文档)。ready(function(){//window。show data=function(数据){//console。信息('调用显示数据’);////var result=JSON.stringify(数据);//$('#text ').val(结果);//} $('#btn ').单击(函数(){ $).Ajax({ URL : ' http://localhost :9090/student ',类型: 'GET ',数据类型: 'jsonp ',//指定服务器返回的数据类型jsonpCallback: ' showData ',//指定回调函数名称成功:函数(数据){ console.info('调用成功');} });});});/脚本/流浆池输入id='btn' type='button' value='跨域获取数据/text area id=' text ' style=' width : 400 px;height : 100px '/textarea/body/html效果图:

再看看如何改变回收这个名称:第23行代码

指定回收这个名称后,后台也需要跟着更改。

"%@"页面页面编码="utf-8 "内容类型="文本/html;charset=UTF-8 "语言="Java"% html标题跨域测试/title脚本src=' http : js/jquery-1。7 .2 .js /脚本脚本函数显示数据(数据){ console.info('调用显示数据’);var result=JSON.stringify(数据);$('#text ').val(结果);} $(文档)。ready(function () { $('#btn ')).单击(函数(){ $).Ajax({ URL : ' http://localhost :9090/student ',类型: 'GET ',数据类型: 'jsonp ',//指定服务器返回的数据类型jsonp: ' theFunction ',//指定参数名称jsonpCallback: ' showData ',//指定回调函数名称成功:函数(数据){ console.info('调用成功');} });});});/脚本/流浆池输入id='btn' type='button' value='跨域获取数据/text area id=' text ' style=' width : 400 px;height : 100px '/textarea/body/html后台代码:

受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)引发ServletException,IOException { response。setcharacter编码(' UTF-8 ');回应。setcontenttype(' text/html;字符集=UTF-8 ';//数据list学生学生列表=getstudent list();JSON数组JSON数组=JSON数组。来自对象(studentList);字符串结果=JSonarray。ToString();//前端传过来的回调函数名称字符串回调=请求。GetParameter(' fffunction ');//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了结果=回调(“结果”);response.getWriter().写(结果);}效果图:

最后看看jsonp是否支持邮政方式:ajax请求指定邮政方式

可以看到,jsonp方式不支持邮政方式跨域请求,就算指定成邮政方式,会自动转为得到方式;而后端如果设置成邮政方式了,那就请求不了了。

jsonp的实现方式其实就是脚本脚本请求地址的方式一样,只是创建交互式、快速动态网页应用的网页开发技术的jsonp对其做了封装,所以可想而知,jsonp是不支持邮政方式的。

"%@"页面页面编码="utf-8 "内容类型="文本/html;charset=UTF-8 "语言="Java"% html标题跨域测试/title脚本src=' http : js/jquery-1。7 .2 .js '/script脚本$(文档)。ready(function () { $('#btn ')).单击(函数(){ $).Ajax({ URL : ' http://localhost :9090/student ',键入: 'POST ',//post请求方式数据类型: 'jsonp ',jsonp: '回调',成功:函数(数据){ var result=JSON.stringify(数据);$('#text ').val(结果);} });});});/脚本/流浆池输入id='btn' type='button' value='跨域获取数据/text area id=' text ' style=' width : 400 px;height : 100px '/textarea/body/html效果图:

再补充一点,回到第一条:CORS头缺少访问控制允许来源。

有时候你会发现其它都没问题,出现这个错误:这个错误代表服务端拒绝跨域访问。如果出现这个错误,就需要在服务端设置允许跨域请求。

回应。setheader('访问控制-允许-源',' * ');设置允许任何域名跨域访问

设置可以跨域访问:第6行代码或第8行代码,设置其中一个即可。

受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)引发ServletException,IOException { response。setcharacter编码(' UTF-8 ');回应。setcontenttype(' text/html;字符集=UTF-8 ';//* 表示允许任何域名跨域访问回应。setheader('访问控制-允许-源',' * ');//指定特定域名可以访问回应。setheader(' Access-Control-Allow-Origin ',' http : localhost :8080/');//数据list学生学生列表=getstudent list();JSON数组JSON数组=JSON数组。来自对象(studentList);字符串结果=JSonarray。ToString();//前端传过来的回调函数名称字符串回调=request.getParameter('回调');//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了结果=回调(“结果”);response.getWriter().写(结果);}总结

JQuery ajax以jsonp类型发起跨域请求,其原理与脚本请求相同,因此在使用jsonp时,跨域请求只能由GET发起。跨域请求需要服务器和回调的配合才能完成跨域请求。

好了,这就是本文的全部内容。希望本文的内容能给你的学习或工作带来一些帮助。有问题可以留言交流。谢谢你的支持。

版权声明:如何使用jquery通过jsonp发起跨域请求及其原理是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。