前后端交互手段之JSONP

什么是JSONP?

JSONP(JSON with Padding(拿json格式的数据去填充 callback))是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题,它是通过script的src属性实现的

什么是跨域?

浏览器从一个域名的网页去请求另一个域名的资源时,
域名、端口、协议任一不同,都是跨域

为什么会有跨域问题–同源策略?

因为浏览器出于数据安全性的考虑,不允许我们向别的服务器发送请求,只能想自己的服务器发送请求,否则会出现跨域,当服务器的域名,端口,协议,有任意一个不同时,就会触发同源策略,跨域请求就是触发同源策略的请求

那么跨域时,浏览器发送了请求吗?服务端响应了吗?

给浏览器一个请求的地址,浏览器就会发送请求,这是浏览器的特性,所以请求肯定是发送出去了,而且服务器也接收到了浏览器的请求,并返回了数据,因为浏览器的同源策略并不能限制服务器的行为,那么为什么浏览器接收不到响应呢?
因为在服务器响应回来数据后,浏览器会先对这个数据进行判断,如果发现请求的不是自己的服务器(也就是跨域了),那么浏览器会认为这个数据是不安全的,就会把数据扔掉,所以浏览器接收不到数据

不受同源策略的标签有哪些?

1,<script src=’’ “></ script>
在src属性中书写请求地址,返回的数据会被解析成js文件来执行
2,< link href=” “/>
这里可以获取别人家的css地址,在当前浏览器中会被解析成css样式
3,< img src=” “/>
获取别人家的图片地址字符串,当前浏览器解析成图片地址
4,< iframe src=” https:www.xxx.com"></ iframe>
src中的网页地址字符串,当前浏览器解析成网页地址

如何用JSONP实现跨域请求

1,首先jsonp是通过script的src属性来实现的,所以我们要创建一个script标签,点击按钮触发网络请求,将script标签添加到head里面

<body>
    <button id="btn">点我发送网络请求</button>//给一个按钮
</body>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script>

    $("#btn").click(function(){

        var sc=document.createElement('script')//创建一个script标签
        url='http://jsonplaceholder.typicode.com/posts'
        sc.src=url;//这个时候还在内存中,并没有添加到页面里
        console.log(sc)
        document.querySelector('head').appendChild(sc)

    })
</script>

2,但是这个时候有一个问题,就是点击发送网络请求除了增加了一个标签之外没有反应,服务端到底有没有给我响应呢?
我们可以去network里面查看,发现返回了响应,,那么返回了响应而浏览器接收不到,
问题1:没办法获取到服务器的响应信息。如果有那个容器可以接受响应最好。(浏览器可以告诉服务器我们这里有个容器,你把数据放在我们的容器,然后我就可以使用了)
问题 2. 客户端如何告诉服务器相关的信息(get传参)
那我在这里用express的脚手架快速生成一个web服务,
在路由文件user.js中手动模拟一组json数据,
再将这个数据返回
开启一下服务器
express --view=ejs myapp

function fn(data){
        console.log(data);
    }//第二步,在这里定义一个函数fn,当浏览器接收到响应时,就在这里执行
    $("#btn").click(function(){
        var sc=document.createElement('script')//创建一个script标签
        url='http://localhost:3000/users?callback=fn'//第一步,先通过get传参的方式
        //告诉服务器我这里有盒子来装你的响应,我们可以理解为盒子的名字叫做fn,
        //callback是服务器的响应,也就是让服务器把数据装在fn这个盒子里传过来就行了
        sc.src=url;//这个时候还在内存中,并没有添加到页面里
        console.log(sc)
        document.querySelector('head').appendChild(sc)

    })
router.get('/', function(req, res, next) {
//第三步,因为浏览器传了信息过来,我在这里获取它传过来的信息,这个时候,服务器已经知道有一个盒子叫做fn来装我的数据了
 var callback= req.query.callback
 //在这里写一个模拟的数据,但是其实本来这里的数据是通过数据库得到的
  var userData = [
    {
      id: 1,
      name: 'andy',
      age: 12,
    },
    {
      id: 2,
      name: 'mark',
      age: 22,
    },
    {
      id: 3,
      name: 'lily',
      age: 12,
    }
  ];
  //第四步,因为浏览器那边的盒子叫做fn,所以我现在把响应装在盒子里
  //下面这种写法的拼接结果传到浏览器端就相当于是这样子的fn([{},{},{}])
  // 目前的拼接: json with padding 拿json格式的数据去填充 callback
  //传到浏览器就可以调用fn函数执行,交互完成
  var fn=callback+'('+JSON.stringify(userData)+')'
    res.send(fn);
    })

然后在浏览器端就接收到了响应
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值