Jsonp解决ajax的跨域问题

这次给大家带来Jsonp解决ajax的跨域问题,Jsonp解决ajax跨域问题的注意事项有哪些,下面就是实战案例,一起来看一下。

一、介绍

最近跨域问题比较多,而且自己刚好也看到这一块,就总结了一下,关于JSONP的东西百度的话东西确实很多,很多人都是复制别人的,如此下去,其实找的资料就那么几份,关键是我还看不懂,可能是能力问题吧,自己经过很多尝试,所以总结了一下,终究还是弄懂了皮毛。注意一点是,这里是用Jsonp解决ajax的跨域问题,具体的实现其实不是ajax。

1、同源策略

浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(JavaScript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

2、JSONP

JSONP(JSON with Padding)是JSON的一种”使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的script 元素是一个例外。利用 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

二、实践

1、模拟跨域请求

在本机弄两个tomcat,端口分别为8080,8888,也就满足了非同源的条件,那么要是从一个端口发送ajax去获取另外一个端口的数据,那么肯定会报跨域请求问题。

这里写图片描述

这里有两个项目,分别是jsonp(8080),other(8888),在jsonp项目中index.jsp如下:

Insert title herefunction jsonp_fun(){$.ajax({url:'http://localhost:8888/other/index.jsp',type:'post',dataType:'text',success:function(data){console.log(data);}});}

登录后复制

other(8888)项目中index.jsp如下:// 因为jsp实际就是servlet,这里就用jsp代替servlet演示。

Insert title hereother domain

登录后复制

其实中上面看无非就是jsonp页面中点击按钮ajax去获取other页面中的数据。

结果如下:chrome控制台

这里写图片描述

XMLHttpRequest cannot load http://localhost:8888/other/index.jsp. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8080’ is therefore not allowed access.

以上提示就是指跨域问题,不能从8080这个域去访问8888域的资源。

2、利用script标签去访问other域的js文件

由于标签的src是支持跨域请求的。最常见的就是CDN服务的应用啦,比如我项目中,如果想用jQuery,但是就没有这个js文件,去下载要找很久,而且版本还不知道下的对不对,那么可以百度搜jquery cdn,我随便找一个,比如bootstrap的cdn:http://www.bootcdn.cn/jquery/,有很多版本供你选择,只要在项目中加上就行了,最大缺点的话就是你没网的话,就引入不到啦。

2.1 在other根路径创建js/other.js文件,内容如下:

alert("this is other(8888) js");

登录后复制

2.2 在jsonp/index.jsp中,加入script标签,引入other的js


登录后复制

进入http://localhost:8080/jsonp/index.jsp,会立马弹出alert,表示引入的js文件自动执行了,跨域请求js成功。

这里写图片描述

2.3 同样的,直接引用,会立马执行立马的alert,那么在other.js中写函数,同样jsonp/index.jsp中也能调用到,这点就不演示了,项目开发中大多都是这样做的,页面与js/css分离。

2.4 另外说明一点,如果在other.js中有函数通过ajax调用8080中的东西,然后引入之后,调用这个函数,也是可以的,但是如果other.js中函数ajax调用8888的东西,引入之后,调用这个函数,同样是跨域的。

3、script实现跨域请求

3.1 简单模拟服务器返回数据

将jsonp/index.jsp改成如下:这里注意引入的other.js的位置,是在函数getResult之后的,如果在它之前的话,会提示函数不存在。js加载顺序是从上开始,在之前调用没创建的,不能成功。注意这里是指引入的js文件,如果是同一个js文件或者当前页面的js中,先执行调用,然后再写函数也是没有问题的,但是如果先执行调用引入js文件中的函数,然后再引入js文件,就会提示函数不存在。


登录后复制

然后other.js

getResult({“result”:”this is other domain’s data”});

也就是在jsonp/index.jsp页面写好函数,然后引入其他域的js传入参数去调用这个函数,这里的参数你可以先看做是其他域服务器的接口返回的数据。

刷新页面,效果当然是

弹出alert框,this is other domain’s data

3.2 模拟接口访问

看到这里,你会不会还是想不懂,上面js弄啥的,传个死的数据,有什么实际意义吗?,其实script的src不仅可以接js的地址,还可以接servlet的地址,也就是http接口地址,所以接下来,懒得写servlet,这里还是写jsp当做接口,在other项目中新建other.jsp页面,内容如下:


登录后复制

内容很简单,也就是接受一个params的参数,然后返回数据给调用者。

我们在jsonp/index.jsp中加上


登录后复制

看到这个地址,你是不是很熟悉,不熟悉的证明你用servlet用蠢了,jsp也是servlet,流程就是页面一加载的时候,script标签就会去发送请求,然后返回数据。那么我们刷新页面,看看效果。

这里写图片描述

Uncaught SyntaxError: Unexpected identifier

报错了,如上,然后代码有问题?No,点击错误,你会看到请求的东西也打印出来了,就是提示错误,表示这个东西浏览器不认识,其实是script不认识啦。

这里写图片描述

还不明白,那么你去页面加上如下内容,你看报不报错!!肯定报错

ajax cross success,the server receive params : jsonp_param

登录后复制

那么js不能解析,我们换一种思路,要是我们输出的是JSON字符串或者调用当前页面函数的字符串了,类似于3.1中返回的getResult({“result”:”this is other domain’s data”});

所以改造一下,把other.jsp中的内容改成


登录后复制

别忘了,之前jsonp/index.jsp中我们定义了,那么加入引用之后,依然记得getResult函数与引入函数的先后顺序问题。


登录后复制

刷新页面,发现大工告成。

这里写图片描述

至此,大部分原理已经讲完了,还有一个问题,这里服务器返回的是getResult(xxx),其中这里的xxx可以当做是经过接口的很多处理,然后塞进去的值,但是这个getResult这个函数名,调用方与其他域服务器这一方怎么约定这个名字是一致的了,况且很多公司自己做服务的,别的公司的开发人员去调用,难道每个人都去那么公司去约定调用函数的名字?怎么可能,所以有人就想出来了一种解决方案,当然不是我~~,其实也很简单啦,也就是把回调的函数名字也一起传过去不就行了,所以代码如下:


登录后复制

other.jsp


登录后复制

代码很简单,也就是传递一个回调函数的参数名,然后经过该接口一系列操作,将返回数据,塞到回调函数里面,调用端的函数就得到了该接口的数据,也就是类似于ajax中succsss:function(data),然后处理data一样,这里的success回调函数,相当于上面的getResult函数。当然你也可以写的优雅一点,比如:

function CreateScript(src) {$("").attr("src", src).appendTo("body")}function jsonp_fun(){CreateScript("http://localhost:8888/other/other.jsp?params=fromjsonp&callback=getResult")}

登录后复制

4、Jquery的JSONP

至此跨域请求的原理已经讲清楚了,但是仍然还有一个问题,总觉得这样用有点怪是不是,如果用jquery的话,调用就很简单了,其实jquery底层实现也是拼了一个script,然后指定src这种方式,跟上面讲的一样,只是jquery封装了一下,显得更加优雅,跟ajax调用方式差不多,所以容易记,代码如下:

function getResult(data){alert("through jsonp,receive data from other domain : "+data.result);}function jsonp_fun(){$.ajax({url:'http://localhost:8888/other/other.jsp',type:'post',data:{'params':'fromjsonp'},dataType: "jsonp",jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)jsonpCallback:"getResult",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以不写这个参数,jQuery会自动为你处理数据success: function(data){},error: function(){alert('fail');}});}

登录后复制

这里的jsonCallback,回调函数设置为getResult,那么返回后会先调用getResult函数中的代码,再调用success函数中的代码,一般情况下,不用定义getResult函数,同样jsonCallback不需要设置,那么就只执行success中的代码,也就跟平时的ajax一样用啦。

所以实际工作用法如下:

function jsonp_fun(){$.ajax({url:'http://localhost:8888/other/other.jsp',type:'post',data:{'params':'fromjsonp'},dataType: "jsonp",jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)success: function(data){alert("through jsonp,receive data from other domain : "+data.result);},error: function(){alert('fail');}});}

登录后复制

这里没有指定jsonpCallback,实际上jquery底层拼装了一个函数名,当然生成函数规则就没研究了。

这里写图片描述

补充:

1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;

2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加标签来调用服务器提供的js脚本。

3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。

4、还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

Ajax+Session失效后即刻跳转登录页面

ajax操作全局监测,用户session失效怎么处理

以上就是Jsonp解决ajax的跨域问题的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2775163.html

(0)
上一篇 2025年3月8日 14:19:49
下一篇 2025年2月24日 17:06:56

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Ajax如何实现无闪烁定时刷新页面效果

    这次给大家带来Ajax如何实现无闪烁定时刷新页面效果,Ajax实现无闪烁定时刷新页面效果的注意事项有哪些,下面就是实战案例,一起来看一下。 在Web开发中我们经常需要实现定时刷新某个页面: 1.来保持session的值或者检查session…

    编程技术 2025年3月8日
    200
  • ajax基本通用代码有哪些

    这次给大家带来ajax基本通用代码有哪些,使用ajax基本通用代码的注意事项有哪些,下面就是实战案例,一起来看一下。 本文实例讲述了ajax基本通用代码。分享给大家供大家参考,具体如下: var xmlhttpfunction loadXM…

    编程技术 2025年3月8日
    200
  • 深入理解js原型链

    这篇文章主要介绍了深入理解js原型链,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 1、原型链:实例对象和原型对象之间的关系,这种关系通过原型(_proto_)来联系的 实例对象的原型_proto_指向的是该对…

    2025年3月8日 编程技术
    200
  • 浅析JS垃圾收集机制和内存管理

    这篇文章主要介绍了浅析JS垃圾收集机制和内存管理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧   垃圾收集   javascript中的垃圾收集机制很简单:找出那些不在使用的变量,然后释放他们.     局部…

    编程技术 2025年3月8日
    200
  • Ajax使用jsonp方式跨域获取数据详解(附代码)

    这次给大家带来Ajax使用jsonp方式跨域获取数据详解(附代码),Ajax使用jsonp方式跨域获取数据的注意事项有哪些,下面就是实战案例,一起来看一下。 jsonp的调用,今天碰到了,正好整理了一下。 $(document).ready…

    编程技术 2025年3月8日
    200
  • Ajax怎么实现局部刷新商品数量和总价

    这次给大家带来ajax怎么实现局部刷新商品数量和总价,ajax实现局部刷新商品数量和总价的注意事项有哪些,下面就是实战案例,一起来看一下。 1. 问题的分析   先看一下页面中的情况:     功能如上,在没有Ajax之前,一般都是根据用户…

    2025年3月8日
    200
  • Ajax怎么发送和接收二进制字节的数据

    这次给大家带来Ajax怎么发送和接收二进制字节的数据,Ajax发送和接收二进制字节的数据的注意事项有哪些,下面就是实战案例,一起来看一下。 HTML5 Ajax 2.0标准中,增强了Ajax的许多功能,包括发送FormData数据,上传数据…

    编程技术 2025年3月8日
    200
  • JS如何对组件实现动态处理

    这篇文章主要介绍了js如何对组件实现动态处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 组件的动态添加,p的复制   对组件的动态处理是动态网页的必备技能。这种情况基本无法避免。就好比如客户需要填写表单,但…

    2025年3月8日 编程技术
    200
  • JS+ajax实现php异步提交表单

    这次给大家带来JS+ajax实现php异步提交表单,JS+ajax实现php异步提交表单的注意事项有哪些,下面就是实战案例,一起来看一下。 很多时候需要异步提交表单,当表单太多是时候,一个个getElementById变得很不实际 当然,j…

    编程技术 2025年3月8日
    200
  • laypage分页插件+ajax怎样做出异步分页

    这次给大家带来laypage分页插件+ajax怎样做出异步分页,laypage分页插件+ajax做出异步分页的注意事项有哪些,下面就是实战案例,一起来看一下。 本文实例为大家分享了laypage前端分页插件,ajax异步分页,获取json数…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论