一起用futureJsonp解决你跨域的烦恼吧

jsonp

什么叫做jsonp,其实就是一种通过利用script标签可以跨域的特性来解决我们不能跨域访问的问题 的方式,所以jsonp不是什么高大上的东西,就只是一种帮助我们解决问题的方式。

常用的jsonp的实现方式

常规情况下,我们通常会用ajax的jsonp请求,或者vue-resource的vue.$http.jsonp的请求来实现跨域访问。不得不说的一点是:其实jsonp请求在彻底的前后端分离应用中还是很频繁的。

jsonp原理

我们都知道,如果前端跨域请求的话,直接通过ajax去请求某个跨域的网站,其实会在浏览器的控制台返回一串错误信息,大概内容是:cross-domain-not-allowed,翻译过来的意思就是不允许跨域。

很多人就急眼了,其实,会后端开发的人呢,通过会通过后端实现http/https请求就可以解决跨域的问题。但是这个问题可难住了前端工程师了。

聪明的人呢,会发现,我们经常访问的百度、腾讯的网站,引入的js,其实都是跨域引入。所以就有人会思考,我们是否可以利用这个一个特性来解决问题。答案是肯定的。

首先我们得了解下script标签的作用原理:

script标签去请求服务器的一个资源的时候,会把返回的结果的上下文解析成是javascript类型,说白了就是返回的内容是一个脚本,并且马上以脚本的形式去执行返回的脚本。jsonp就是利用这么一个原理,通过后台动态回调前端的js实现跨域请求。

jsonp实现

假如我们要请求http://jsonp:6666/sayHello这个一个远端请求,携带参数有{name:11,age:"2222"},利用jsonp方式最简单的实现就是:

1、先拼凑好请求url和参数,jsonp请求过程只能通过地址栏传参方式,即get方式传参,拼凑后的结果就是:http://jsonp:6666/sayHello?name=11&age=2222

2、直接在页面即html里头添加一个script节点,设置该script节点的src属性为:http://jsonp:6666/sayHello?name=11&age=2222

3、直接打开页面这个时候没有半点反应,但是呢,通过f12打开浏览器的开发者工具,切换到network视图,如下设置:

4、刷新当前网页,会发现我们刚刚设置的script,请求已经被发出去了。这个时候,可以通过如下视图查看返回信息(下面的请返回值我已经做了特殊处理,你们正常只能看{"code":"ok","data":"get请求"}):

可以看到请求已经成功。但是请求的结果,我们没办法利用。

5、现在回想下,刚刚我们说了,返回的内容会被以javascript的形式被执行,所以我们是不是只要后端把传回来的参数转成json字符串,然后用一个方法名字符串拼凑起来,如: yHWxYLSb2811({"code":"ok","data":"get请求"}),注意:yHWxYLSb2811要在前端有定义。这样当请求成功之后,是不是相当于由后端调用了前端的yHWxYLSb2811方法。

6、上述5个步骤之后,一个最为简单的jsonp请求就完成了。

进阶

讲了这么多,笔者总是有一颗封装的心。上述步骤虽然可以实现原始的jsonp请求,但是灵活用,简便用,好用,显然还够不着,是否可以做成像ajax的get、post请求那样,都封装好了,要用的时候只要调用一个方法就可以呢,答案是肯定的,不然我都不敢写这个博文了。

笔者封装的jsonp插件介绍如下:

futureJsonp插件

名称

futureJsonp

用法

/**
 * 发起jsonp请求插件
 * options:{
 *  url:[string] 必传 请求的跨域地址
 *  callback:[func] 非必传 请求成功的回调函数,方法体就是写我们的业务处理逻辑
 *  params:[json] 非必传 请求的参数
 * }
 */
futureJsonp.jsonp({
        url:"http://localhost/vResourceJonp?name=111",
        callback:function (result) {
            // result是请求服务器的返回值
        },
        params:{age:11,sex:1}
    });

futureJsonp.js源码

/**
 * @author:扫地僧
 * @time:20190705
 */
var futureJsonp={};futureJsonp.errorPre="【error:future-jsonp】";futureJsonp.updateQueryStringParameter=function(uri,key,value){if(!value||!key){return uri}var re=new RegExp("([?&])"+key+"=.*?(&|$)","i");var separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}else{return uri+separator+key+"="+value}};futureJsonp.randChar=function(cLength,nLength){var characters="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";var numbers="0123456789";characters=characters.split("");numbers=numbers.split("");var cResult="";var nResult="";while(cResult.length<cLength){var tmp=Math.round(Math.random()*characters.length);tmp=tmp==characters.length?(tmp-1):tmp;cResult+=characters[tmp]}while(nResult.length<nLength){var tmp=Math.round(Math.random()*numbers.length);tmp=tmp==numbers.length?(tmp-1):tmp;nResult+=numbers[tmp]}return cResult+nResult};futureJsonp.jsonp=function(options){if(!options){console.error(futureJsonp.errorPre+"the jsonp func need one param");return}var url=options.url;if(!url){console.error(futureJsonp.errorPre+"you need confirm whether designate the url");return}var id=futureJsonp.randChar(8,4);console.log(id);var tmp=options.callback;var callback=function(result){if(tmp){tmp(result)}eval(id+" = null;");var idObject=document.getElementById(id);if(idObject!=null){idObject.parentNode.removeChild(idObject)}};eval("("+id+"=function (result) {callback(result)})");var params=options.params;if(!params){params={}}params.callback=id;for(var key in params){url=futureJsonp.updateQueryStringParameter(url,key,params[key])}var script=document.createElement("script");script.type="text/javascript";script.src=url;script.id=id;document.getElementsByTagName("head")[0].appendChild(script)};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行侠_阿涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值