给自己的无知记一次过(jsonp的跨域请求)

写在前面:最近在回顾ajax请求时,对跨域数据请求产生了极大的兴趣,奈何刚开始自己天真的以为jsonp无敌到可以跨域拿到任何开放接口的数据,于是开启了自己的踩坑之路。最先是顺利的用jsonp拿到了淘宝的搜索框提示,以为“就这”。谁曾想痛苦来的那么突然,接着在请求一些网上免费接口时便陷入深渊,那么来分享一下我的爬坑之路。

入坑

1. 用jsonp请求淘宝搜索框提示

  1. 原提示框:

在这里插入图片描述

  1. 打开开发者工具,找到搜索接口,自己用jsonp请求此接口:

示例代码:

 $.ajax({
                // 请求地址
                url: 'https://suggest.taobao.com/sug',
                // jquery的jsonp请求必带参数
                dataType: 'jsonp',
                // 根据原请求地址写入参数
                data: {
                    code: 'utf-8',
                    q: '键盘',
                    extras: '键盘',
                    area: 'c2c',
                    bucketid: 'atb_search',
                    unid: '',
                    clk1: '',
                    pid: 'mm_50570328_39070332_145428725',
                },
                // 请求成功时返回数据
                success: function(data) {
                    console.log(data)
                }
            })

注意:对于jsonp请求的了解可查看此小姐姐的文章,很详细,自己也有学到(https://blog.csdn.net/m0_38134431/article/details/84393158

  1. 发送请求拿到数据:

在这里插入图片描述
总结:jsonp的原理大家看完文章一定已经很清楚了,那么它请求数据的原理为函数的调用,如上图。

翻车

2. 开始用一些网上的免费接口

  1. 写请求代码:
$.ajax({
                url: 'http://api.avatardata.cn/ShengXiaoPeiDui/Lookup',
                dataType: 'jsonp',
                data: {
                    key: '1028fe71be664298a07485e8e460557a',
                    shengxiao1: '虎',
                    shengxiao2: '兔'
                },
                success: function(data) {
                    console.log(JSON.parse(data))
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest.status);
                    console.log(XMLHttpRequest.readyState);
                    console.log(textStatus);
                }
            })
  1. 请求的响应结果:

在这里插入图片描述

  1. 自救过程:
  • 我以为是jquery封装的jsonp严格模式的原因,就用了自己封装的jsonp,可结局一样。
  • 我惊奇的发现,虽然没有打印请求数据,但结果竟然可手动访问,我这“改变世界的冲动就上来了”,一顿操作,没得啥用。
  • 我看到报的警告,用我这中国式英语,也算翻译了一通(跨源读取阻塞(CORB)阻塞的跨源响应“”使用MIME类型application/json。)
  • 起初的我还不以为然,没有加error函数,结果“头都碰烂了”(各种百度,各种查),以为Google晃我。接着加上error函数,又是一顿查,报错就离谱,哈哈哈。兜兜转转一天就这样过去了哈。
  • 最后才开始注意打印的“parsererror”,是:文本分析器错误,简单点:请求方式与返回数据格式冲突,奈何都到这一步了,本人还是认为jsonp无敌,哈哈哈。

爬坑

意识到问题着手解决

1. 开始各种搜
  1. 开始了解“parsererror”相关的文章,看看有没有同学跟我一样,结果发现还是自己最菜(哈哈哈)。
  2. 开始对json、jsonp的数据格式进行了解,还是这位小姐姐的文章让我发现了自己请求的问题,相关文章(https://blog.csdn.net/m0_38134431/article/details/83787452
  3. 奈何还是无果,因为我坚信jsonp跨域无敌(啪啪打脸)。
  4. 最后没能忍住对知识的渴望,还是请教了这位小姐姐,人家非常耐心的回复了我,人真的超好。
2. 成功脱坑
  1. 最终知道了jsonp不是无敌的。
  2. 因为自己请求的那个接口支持数据类型为json/xml,不支持函数的调用。
  3. 因为自己最初接触jsonp时,要么是访问本地服务器,要么是老师讲的就是一些支持jsonp请求的接口。让自己误以为jsonp辣么强(跨域无限制)。
  4. jsonp请求要想成功,必须有服务器端返回的函数调用,函数的参数作为数据.
  5. 数据接口大多支持json、xml格式;切记不是所有的接口都支持jsonp请求,毕竟jsonp请求只支持get方式,安全方面有待考量

拓展

接着再对那个接口进行请求

那么问题来了,服务器不支持jsonp请求,如何拿到数据。此处用到了访问非同源数据,自身服务器的解决方案
了解更多同源政策,可看在下的另一篇文章(https://blog.csdn.net/cwq521o/article/details/106000280

此处请求的原理为:服务器端不受同源政策的限制:配置本地服务器访问远程接口(拿到请求数据),再有客户端访问本地服务器(拿到数据)

1. 配置本地服务器
// 引入express框架
const express = require('express');
// 引入核心模块path(路径)
const path = require('path');
// 引入请求服务器模块request
const request = require('request');
// 声明服务器
const app = express();

// 访问静态资源
app.use(express.static(path.join(__dirname, 'public')));

// 建立本地请求路由
app.get('/serice', (req, res) => {
    request(' http://api.avatardata.cn/ShengXiaoPeiDui/Lookup?key=1028fe71be664298a07485e8e460557a&shengxiao1=' + encodeURI(req.query.shengxiao1) + '&shengxiao2=' + encodeURI(req.query.shengxiao2) + '', (err, respones, body) => {
        res.send(body);
    })

    // res.send('ok')
})

// 监听端口
app.listen(3000, () => {
    console.log('服务器启动成功,端口3000')
})
2. 写请求代码(ajax请求)
<input type="text" name="" id="shengxiao1">
    <input type="text" name="" id="shengxiao2">
    <button>发送</button>
    <script>
        $("button").on('click', function() {
            $.ajax({
                type: 'get',
                url: 'http://localhost:3000/serice',
                data: {
                    shengxiao1: $("#shengxiao1").val(),
                    shengxiao2: $("#shengxiao2").val(),
                },
                success: function(data) {
                    console.log(data)
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest.status);
                    console.log(XMLHttpRequest.readyState);
                    console.log(textStatus);
                }
            })
        })
    </script>

注意:ajax请求,支持get,post以及RESTful风格的API,此处用get请求

3. 客户端发送请求

在这里插入图片描述
最后,成功通过跨域拿到此接口数据。长舒一口气,害。

在这里插入图片描述
数据格式,告诉我了一切,哈哈哈。

最后

写在最后:希望自己今后所学要多进行扩展性的实践,“多给自己找茬”,学习要有深度,再有广度。对基础知识定期回顾,以免再酿成今天的事故。还是非常感谢帮助到自己的博主们(点名表扬神秘小姐姐),我们一起加油,Come on

猜你喜欢

转载自blog.csdn.net/cwq521o/article/details/106605794