zoukankan      html  css  js  c++  java
  • 跨域请求之jsonp

    聊聊什么是jsonp

    说到son大家应该是很熟悉的,jsonp和json只差了一个字母,那么他们是不是他们有着非常密切的关系呢?答案是确定的。jsonp全称”JSON with Padding“,意思应该是”填充的json“。那么问题就来了,填充指的是什么,怎么填充呢?

    聊聊script标签

    <script> 标签用于定义客户端脚本,比如 JavaScript。<script type="text/javascript">

    script 元素既可以包含脚本语句,也可以通过 src 属性指向外部脚本文件。

    当使用src属性时,script标签就会去请求目标资源。利用这一特性,我们就可以用script标签去请求服务器的json数据,这就是jsonp。

    其实真正可以使用src属性的标签并不只有script,img等标签一样可以,但他们都不用于请求json,因此不属于jsonp范畴。

    那么怎么实现动态请求数据和设置回调函数处理数据呢?

    1. 动态生成script标签
    2. 将url赋值给src
    3. 注册回调函数
    4. 将script标签append进dom树
    5. 执行回调函数

    代码如下:

    function jsonp( url, fn ){
        //构造一个函数到window上
        var fnName="__jsonpFn"+Math.random().toString().replace(".","");
        //创建script标签
        var script=document.createElement("script"),
        //获得页面中的head标签
            head=document.head;
        //设置script标签请求的src,记得带有参数
        script.src=url + "?callback=" + fnName;
        //先绑定函数,再请求更加安全
        window[fnName]=function( data ){ //发回数据调用的内容
            fn(data);  //用户写的函数
    
            //删除函数,删除内容
    
            delete window[fnName];
            head.removeChild( script );
        };
    
        //将script标签加到页面中,浏览器就会自动的请求下载js格式的字符串
        head.appendChild(script);
    }

    服务端:

    var express = require("express")
    var app = express()
     
    
    app.get('/api', function (req, res) {
        var data={
            name: "王八",
            age: 100
        }
        //返回的类型必须设置为javascript
        res.type('text/javascript')
        //前端路由中的参数获取,req.query。
        console.log("query",req.query);
        res.send(req.query.callback+'(' +JSON.stringify(data)+')')
        //这里的数据必须转化为字符串,否则传入一个对象浏览器无法解析
        // res.send(req.query.callback+'(' +data+')')
    })
    app.listen(3000)
    console.log("listen the port 3000");

    补充说明:

    也许有的小伙伴不明白回调函数是怎么被触发的,关键在这两行代码

     res.type('text/javascript')
     res.send(req.query.callback+'(' +JSON.stringify(data)+')')

    这两行相当于往你注册的script标签写入了fnName(data),作用便是触发前面window上注册的回调函数,而这个data在服务端动态生成并以实参形式嵌入在返回的函数中,其实这就是上面提到的”填充的json“,

    真正的json数据就是这样被填充在实参里返回了。

    整个过程就相当于你手动干了这么一件事:

    <script type="text/javascript" src="url">
    data = '{"a":1}'
    fnName(data)
    </script>

    服务器的作用就是生成了这个data并嵌套在实参里面返回给你了。

    优缺点:

     1.优点
                    1.1它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制,JSONP可以跨越同源策略;
                    1.2它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
                    1.3在请求完毕后可以通过调用callback的方式回传结果。将回调方法的权限给了调用方。这个就相当于将controller层和view层终于分 开了。我提供的jsonp服务只提供纯服务的数据,至于提供服务以 后的页面渲染和后续view操作都由调用者来自己定义就好了。如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,逻辑都可以使用同 一个jsonp服务。
    2.缺点
                    2.1它只支持GET请求而不支持POST等其它类型的HTTP请求
                    2.2它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
                    2.3 jsonp在调用失败的时候不会返回各种HTTP状态码。
                    2.4缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。

    评价:

    JQ等框架当年都有封装好的jsonp请求,但如今的业务中几乎都看不到jsonp请求了,如今用的最多的都是cors,从便捷度和安全考量,cors都好于jsonp。但jsonp的思想仍在使用,比如利用CDN引入图片等,其实本质上和jsonp原理一样,都是利用src属性去请求跨域资源,只是数据的形式不一样而言。

    参考了以下文章:

    https://cloud.tencent.com/developer/article/1145813

    https://blog.csdn.net/weixin_38888773/article/details/81974348

    https://www.cnblogs.com/ricesm/p/5055043.html

  • 相关阅读:
    clr via c# 定制特性
    clr via c# delegate
    clr via c# Array2
    clr from c# 字符 ,字符串 和 文本处理
    clr via c# 接口
    clr via c# 泛型
    clr via c# 事件
    clr via c# 参数和属性
    程序设计入门——C语言 第6周编程练习 2 完数(5分)
    程序设计入门——C语言 第6周编程练习 1 分解质因数(5分)
  • 原文地址:https://www.cnblogs.com/AwenJS/p/12707050.html
Copyright © 2011-2022 走看看