当前位置: 首页 > Web前端 > HTML5

JSONP

时间:2023-04-05 15:12:20 HTML5

,破解浏览器同源策略的利器。这篇文章是在了解了浏览器的同源规则之后,学习了一个简单有效的破解这个规则的方法->JSONP。主要是通过阮一峰老师的博客学习浏览器的同源规则。有这样一个背景,如果你通过银行网站进行取款的交易,而其他用户通过一定的渠道可以获取到你在银行网站上的信息,那就太可怕了。因此,1995年NetScape(Firefox的前身)提出了浏览器同源策略,目的是保护使用网站的用户的信息安全。那么什么是同源呢?协议相同,域名相同,端口号相同。但是随着互联网的发展,有时候我们需要破解同源,所以首先要学习古老而行之有效的JSONP方法。浏览器如何向服务器提交数据有一天,程序员小白在自学,看到JSONP很不错,就向大程序员小黑请教。小黑小黑,这是什么JSONP,感觉牛逼(⊙o⊙)!.小黑扶了扶五百度的眼镜,摸了摸头顶的几根头发,若有所思的问小白。小白,你说说,浏览器是怎么向服务器提交数据的,比如你要支付。form表单,我规定,不需要get请求。

您的账户余额为200
支付1元嗯,还是不错的,就知道用POST了一个要求。那你提交这个之后,是不是要刷新当前页面才能看到余额?...嘿,是的,但我可以为你添加一个iframe,只需刷新当前页面是所有的反馈信息都显示在iframe中。嗯,没关系,但是为什么页面上写的是总量200呢?不应该从数据库中动态获取吗?&&&amount&&&支付1元...button.addEventListener('click',(e)=>{letn=amount.innerTextletnumber=parseInt(n,10)letnewNumber=number-1amount.innerText=newNumber}我使用&&&amount&&&占位符作为总金额,服务器端可以按如下方式处理它varamount=fs.readFileSync('./db','utf-8')//从db中读取字符串=string.replace('&&&amount&&&',amount)//用真实数据替换占用的数据...response.write(string)嗯,就是这样对了,再想一想,有没有其他方法可以向服务器发送数据,不刷新页面...还有其他的(⊙o⊙)!那我老黑了,我来告诉你资深程序员的方法havetried//用图片发起get请求.innerText-1}image.onerror=function(){alert('汇款失败')}这个也是可以的,也会用来提示用户。交互性还可以,但是只能发起GET请求,哈哈,我就是想炫耀一下我的黑科技,我很少用到。。。(@ο@)哇~这个也可以,小黑,你真棒,学了很多,但是你还没有跟我讲过JSONP,你忘了吗……你没忘记,别着急,接下来,我就给大家讲讲这个JSONP的动态创建JS脚本发送数据小白,你平时使用最多的语言是什么?中文,英文不太好。。。说到编程,呃,那个用了很多JavaScript,好吧,那我们就用js脚本发送数据吧//用js脚本发起请求letscript=document.createElement('script')script.src='/pay'document.body.appendChild(script)script.onerror=function(){alert('failed')}...//服务器通常这样做if(path==='/pay'){varamount=fs.readFileSync('./db','utf8')varnewAmount=amount-1fs.writeFileSync('./db',newAmount)response.setHeader('Content-Type','application/javascript')response.statusCode=200response.write(`amount.innerText=amount.innerText-1`)response.end()}以上是js脚本的大概意思,不用深究了详细点,了解一下。注意,添加脚本后,记得给document.body.appendChild(script)但是,小黑,你动态添加脚本是真的,但是你每次都在我的html底部添加js,这破坏了我的html,嗯,小白,你的思维能力还是不错的,目前确实存在这个缺点,我来给你解决一下//使用js脚本发起请求letscript=document.createElement('script')script.src='/pay'document.body.appendChild(script)script.onload=function(e){e.currentTarget.remove()//加载完成后,remove}script.onerror=function(e){alert('failed')e.currentTarget.remove()//加载完毕,移除}对了,小黑,这波操作你可以做。让我快速认识一下JSONP,好吧,这就给大家展示一下button.addEventListener('click',(e)=>{//使用js脚本发起请求letscript=document.createElement('script')letfunctionName='wushao'+parseInt((Math.random()*100000),10)window[functionName]=function(result){if(result==='success'){amount.innerText=amount.innerText-1}else{}}script.src='http://你想访问的另一个网站:端口号/pay?callback='+functionNamedocument.body.appendChild(script)script.onload=function(e){e.currentTarget.remove()}script.onerror=function(e){alert('failed')e.currentTarget.remove()}})ヾ(?`Д′?)黑神,你跨度有点大,为什么你改了吗?一个大魔术。O(∩_∩)O哈哈~,我快点告诉你吧。。。详细说一下吧letfunctionName='wushao'+parseInt((Math.random()*100000),10)用一个随机函数来建立自己的函数名,可以和服务端代码完美解耦。服务器端只需要获取查询参数?callback=functionName中的functionName即可。window[functionName]=function(result){}给window全局对象加上functionName属性,它的值是一个函数,当服务器响应回来时,浏览器写的这个函数的参数就是服务器成功了,我们知道我的数据成功了。//服务器端只需要这个,不管你写什么函数名搞错了,哈哈,每次都要把添加的全局对象的属性去掉~script.onload=function(e){e.currentTarget.remove()deletewindow[functionName]}script.onerror=function(e){alert('失败')e.currentTarget.remove()deletewindow[functionName]}O(∩_∩)O哈!,这样就对了,小白,既然学了jQuery,可以试试jQuery的写法(^o^)/~行了,小黑,我也换个$.ajax({url:"http://Another我要访问的网站:端口号/pay",//回调参数的名称,由YQL服务指定jsonp:"callback",//告诉jQuery我们需要JSONPdataType:"jsonp",//配合responsesuccess:function(response){if(response==='success'){amount.innerText=amount.innerText-1}}})不错不错小白~O(∩_∩)O哈哈~,我是谷歌的jqueryjsonp。但是,这与ajax无关。不明白jquery为什么要这样写。具体代码链接在============>传送门什么是JSONP?请求者是一个网站(浏览器端),响应者是另一个网站(服务器端)。请求者动态创建一个script脚本,src属性是响应者的地址,同时传递一个查询参数?callback=functionName,一般functionName是使用随机函数构造的。响应者根据接收到的查询参数callback=functionName构造响应,形式为2.1functionName.call(undefined,'success')2.2或直接functionName.('success')。浏览器收到响应后,会执行functionName.call(undefined,'success')或者functionName.('success')这样请求者就知道他想要得到什么数据了。这就是JSONP的原理。为什么JSONP不支持POST请求?答:JSONP是一个动态创建的js脚本。该方法只能发起GET请求,不能发起POST请求。其他的请求,用AJAX来做吧?