想知道jsonp到底是怎么实现的?看我,包教会!

不管你好不好,反正我是番茄酱。为啥要写这篇文章呢,因为我想写。

看这个文章的你肯定是想学会jsonp吧(废话),那遇到这个文章是你的福气。我敢保证这是全网最容易看懂的文章。当然,你如果不会写js,不懂什么叫跨域,那就算了。别勉强了,勉强是没有幸福的(而且你也没有学习jsonp实现方法的必要)。

首先声明,这篇文章不涉及后台代码的具体实现,关于后台的部分只说思路。

好啦,那我们开课啦!

总的实现思路

我这篇教程的结构是总-分-总(瞎扯的,实际上是总-随意-随意-...-随意)。我们先来说说总的实现思路。

我们都知道由于“同源策略”(不懂啥是同源策略没关系,反正你知道有跨域现象就行了),而导致我们跨域的ajax请求发送失败,浏览器报错。

但是呢script标签的src是没有跨域一说的,也就是说你可以随便引用别的网站的js。这就是总的实现思路。如果不理解这一点,也不用往下看了,因为你以你的知识储备和理解能力不合适看这文章。

说完总的实现思路,我们来看具体怎么做吧。

1:先忘记我们要实现jsonp

先忘了我们的目标,看一下我们需要完成jsonp而需要掌握的知识。先理解了这些,才能理解jsonp的实现。

1.1:基础的js代码

我们在页面写个这样的代码:

<script>
    function a() {
        console.log('hello cat!');
    }
</script>
<script>
    a();
</script>

运行结果:

对于代码和结果没有异议吧。为啥我要写这样的函数。我要说明的是这样一点:后一个script标签里的代码可以引用前一个script代码里的函数(全局)。老规矩,理解了这点就继续往下看。

1.2:script标签引用文本

我们在html里写这样的代码:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>

然后我们在同路径下新建一个a.txt。并且a.txt里的文本如下:

a();

然后我们在html里引用a.txt。完整的代码如下:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script src="a.txt"></script>

刷新页面,控制台如下:

也就是说txt里的代码被执行了。所以a函数才会被执行。我要说明的是:scritpt标签引用的外部文件中的文本内容会被当成js来解析。

也就是说相当于是这样的代码:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script>
    a();
</script>

1.3:后台返回文本

如果我们的后台给我们返回的不是数据,而是跟a.txt一样的文本如下文本:

a();

如我们请求地址为:https://www.a.com/a。则我们此时的完整代码为:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script src="https://www.a.com/a"></script>

那可以预见,最终的结果会与1.2一致。因为也等于是如下的代码:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script>
    a();
</script>

小结

以上的东西只是需要完成jsonp要懂的知识。你理解了可以继续往下看。先不要深究“这样怎么能实现”的问题。不要急,我后面会说的。如果不理解上面的知识可以多看几遍。能够自己动手实验最好。

2:再看看一般的ajax请求

我们一般的ajax请求,是后台给我们一个请求地址,我们发送请求,然后后台返回给我们json格式的信息。例如我们要请求的地址是:

https://www.a.com/userInfo (获取用户信息)

后台应该返回给我们的数据是:

{
  "name": "番茄酱",
  "wechat": "fan_qie_jiang666",
  "qq": "1164431166",
  "email": "1164431166@qq.com"
}

也就是说我们最终需要的是服务器把json格式的数据给我们。但是我们用1里说的方法,虽然服务器能调用我们本地的函数,但是我们怎么能获取到数据呢?

那这样,我们把1.3的html代码改成这样:

<script>
    function a(res) {
        console.log(res);
    }
</script>
<script src="https://www.a.com/userInfo"></script>

服务器返回的文本改成这样:

a({
    "name": "番茄酱",
    "wechat": "fan_qie_jiang666",
    "qq": "1164431166",
    "email": "1164431166@qq.com"
});

也就是相当于这样的代码:

<script>
    function a(res) {
        console.log(res);
    }
</script>
<script>
    a({
        "name": "番茄酱",
        "wechat": "fan_qie_jiang666",
        "qq": "1164431166",
        "email": "1164431166@qq.com"
    });
</script>

最终结果:

也就是说我们获取到了我们需要的数据。但是万一我们的function不叫a,或者原本叫a,但是因为种种原因需要改名,这样后台也要跟着改代码。这增加了沟通成本,也增加了后台的工作量。并且可能每个接口你们都需要去沟通这个函数的名字。这是问题呀!

3.解决函数名的问题

用script标签里的src相当于向服务器发送了get请求。

不管你理不理解上面这点,记住就行了。既然是相当于get请求,那就可以带参。并且后台也能获得这个参数的值。

既然这样那我们是不是跟后台沟通好我们给所有用jsonp的请求弄个参数,这个参数的值是我们本地的函数名。后台直接给我们返回函数名然后参数为数据值就ok辣?不理解的话看下面的过程。

比如我们和后台沟通好参数名叫balabala,那代码就像下面这样:

<script>
    function xiaoMoXian(res) {
        console.log(res);
    }
</script>
<script src="https://www.a.com/userInfo?balabala=xiaoMoXian"></script>

后台收到了这个请求,不再像之前那样直接返回给我们a(...)。

因为我们已经说好了,函数名不再是固定的a,而是balabala这个参数的值才是我们的函数名。

于是后台去获取balabala这个参数的值,获取到的是xiaoMoXian。于是后台返回给我们:

xiaoMoXian({
    "name": "番茄酱",
    "wechat": "fan_qie_jiang666",
    "qq": "1164431166",
    "email": "1164431166@qq.com"
});

于是代码就相当于是:

<script>
    function xiaoMoXian(res) {
        console.log(res);
    }
</script>
<script>
    xiaoMoXian({
        "name": "番茄酱",
        "wechat": "fan_qie_jiang666",
        "qq": "1164431166",
        "email": "1164431166@qq.com"
    });
</script>

最终结果与2相同。

小结

以上就是jsonp的实现过程。我们已经完成了不用ajax来请求,而利用script标签src属性的跨域特性,来实现我们获取数据的目的。

我来小结下我们用到的知识点:

  1. ajax请求受同源策略的影响不能跨域。(问题)
  2. script标签的src是可以跨域的,不受同源策略的影响。(总的方法)
  3. 后一个script标签里的代码可以引用前一个script代码里的函数。
  4. scritpt标签引用的外部文件中的文本内容会被当成js来解析。(结合3可以获取数据)
  5. 用script标签里的src相当于向服务器发送了get请求。(解决函数名的问题)

看到这并且看懂就说明你已经差不多可以毕业了。因为你已经完全懂了jsonp怎么实现的。可是我们一般用jsonp好像没这么麻烦呀,也不用专门去写个函数来给后台调用,也不用去写script标签写src到我们的请求地址,也不用沟通什么参数名。哪像你说的这么麻烦!?

哈哈,我要加班啦。预知后事如何,请多点赞。赞够多我就更。

据量子力学得到,点赞这篇文章的人都会成为欧皇,从此过着开心幸福的生活☺️。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352