跨域的解决方案:JSONP、CORS

解决方案

现代化的 Web 应用中肯定会有不同源的现象,所以必然要解决这个问题,从而实现跨域请求。

参考:http://rickgray.me/solutions-to-cross-domain-in-browser

JSONP

JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。

其原理就是在客户端借助 script 标签请求服务端的一个地址,服务端的这个地址返回一段带有调用某个全局函数调用的 JavaScript 脚本(而非一段 HTML),将原本需要返回给客户端的数据通过参数传递给这个函数,函数中就可以得到原本服务端想要返回的数据。

以后绝大多数情况都是采用 JSONP 的手段完成不同源地址之间的跨域请求

客户端 http://www.zce.me/users-list.html

<script src="http://api.zce.me/users?callback=foo"></script>

服务端 http://api.zce.me/users?callback=foo 返回的结果

foo(['我', '是', '你', '原', '本', '需', '要', '直', '接', '返', '回', '的', '数', '据'])

总结一下:由于 XMLHttpRequest 无法发送不同源地址之间的跨域请求,所以我们必须要另寻他法,script 这种方案就是我们最终选择的方式,我们把这种方式称之为 JSONP,如果你不了解原理,先记住怎么用,多用一段时间再来看原理。

问题:

  1. JSONP 需要服务端配合,服务端按照客户端的要求返回一段 JavaScript 调用客户端的函数
  2. 只能发送 GET 请求

注意:JSONP 用的是 script 标签,更 AJAX 提供的 XMLHttpRequest 没有任何关系!!!

jQuery 中对 JSONP 的支持

jQuery 中使用 JSONP 就是将 dataType 设置为 jsonp

$.ajax({
  url: 'https://douban.uieee.com/v2/comming_soon',
  type: 'get',
  dataType: 'jsonp',
  data: { id: 1 },
  beforeSend: function (xhr) {
    console.log('before send')
  },
  success: function (data) {
    console.log(data)
  },
  error: function (xhr) {
    console.log(xhr)
  },
  complete: function (xhr) {
    console.log('request completed')
  }
})

Axios 由于设计原因不支持 JSONP

案例:

index.html

<script>
    let script = document.createElement('script'); // 创建一个script
    script.src = 'http://localhost:3000/users24?cbk=eee'; // 在cbk设置参数值为 方法名
    document.body.appendChild(script); // 把script 添加到body中

    function ddd(data) {
        console.log(data);
    }
</script>

app.js

var user = require('./db');
app.get('/users23', (req, res) => {
    let cb = req.query.cbk; // 获取函数名 eee
    let newUser = JSON.stringify(user); // 把数据转化成json字符串
    let newStr = ` ${cb}(${newUser})`; // 把执行方法eee 和数据 通过模板字符串传给 前端
    res.send(newStr); // 向前端发送 db.json 的内容
});

db.json

[{
    "name": "姚娟",
    "content": "白周理石快地们等求众真农多局导实。影元看表干克复交员率响当便定群道。度代布大料标拉红感应石加节。今必可何原火其属日条铁金系。构十被从回商值管并少况圆期十山。况市或安开路次美回育市具度。因众铁界别也斯事点极线和别矿。",
    "created": "1992-01-01 21:52:23"
}, {
    "name": "常军",
    "content": "矿说安西件族就写研界政到府。装却事看青写十五层同并达层难果用千家。则素值万议区清办量认入拉省教。展清值心特响起先大市算六为。这战电治你亲别低小会连革能。又东名还家况料东理县际便列每自。断系计照资质切部代当级面号标。",
    "created": "1994-12-01 18:23:42"
}]

CORS

Cross Origin Resource Share,跨域资源共享

app.get('/time', (req, res) => {
  // // 允许任意源访问,不安全
  // res.set('Access-Control-Allow-Origin', '*')
  // 允许指定源访问
  res.set('Access-Control-Allow-Origin', 'http://zce.me')
  res.send(Date.now().toString())
})

这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个 Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前端酱紫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值