美文网首页饥人谷技术博客Vue
HTTP: 跨域真的有这么难吗

HTTP: 跨域真的有这么难吗

作者: 写代码的海怪 | 来源:发表于2019-02-08 02:08 被阅读94次

前言

以前写前端小项目的时候就听说过跨域这个词,什么 JSONP啊,CORS啊。感觉很高级,但是无奈项目太小没机会用上。今天就写篇博客总结一下常用的跨域操作。

为什么要跨域

一般来说写项目的时候都是自己给自己发请求的,如 localhost:8080 发了一个 /users 请求,本质上就是向 localhost:8080/users 发请求,这是被允许的。但是如果给支付宝发是不行的,如 post /zhifubao/sendMoney/user?money=1000,如果允许的话那每个人装一个 postman 不断发请求就可以去支付宝偷钱了(不考虑验证情况下)。所以呢跨域请求是不好的,但是在某些条件下是可以的。像大家都是兄弟公司,虽然我们域名不一样但是我们有 py 交易呀,数据都共享,你发请求给我,我也发请求给你,这就需要跨域请求了。

JSONP

JSONP 其实真名叫:JSON + Padding。JSON 大家都知道跟 JS 对象差不多,是一种通信格式。至于 Padding ,emmm 如果你知道这个原因就感觉很 SB。

为什么会有 JSONP

JSONP 本来不是用来解决跨域问题的,是用来实现发请求时不重刷页面的,这都是 Ajax 出现前的一个技术,或者说是一个替代品,只不过刚好可以用来实现跨域请求。

前端实现

实现思路是

  1. 定义一个 loadData 函数在全局
function loadData(data) {
   console.log(data)
}
  1. 创建一个 <script> 标签,并在 src 加上请求 url 如: /hello?callback=loadData
  2. 添加这个 <script> 标签到 document.body 上。一旦添加了浏览器马上会发一个 /hello?callback=loadData 的 GET 请求
  3. 等服务器响应后,就会执行返回的 JS 代码。一般来说这 JS 代码就是这个 loadData(data),这个 data 是服务器添加上去的,至于怎么返回 JS 代码请看服务端实现

后端实现

  1. 首先获取查询参数里的 callback(回调函数的名字,这里就是 loadData)
  2. 然后生成要返回的数据
  3. 将数据和前端提取出来的回调函数结合,生成 JS 代码,返回到浏览器,浏览器一收到就会执行
app.get('/hello', (req,res) => {
  let callback = req.query.callback;
  let obj = {
    userName: 'Jack',
    password: '123456'
  };
  res.writeHead(200, {"Content-Type": "text/javascript"});
  res.end(callback + '(' + JSON.stringify(obj) + ')');
})

好了,这里说下 Padding 是啥,你看到 userNamepassword 前面的空白没有,那就是 Padding,完。JSON 是因为传入回调函数的数据一般为 JSON 格式。

CORS

CORS 全名是 Corss Origin Resource Sharing。这种方法比较简单,因为前端发请求就好了,后端也正常返回数据。要改的是后端在返回响应时要添加一个响应头。

app.post('/hello',(req,res) => {
  if(req.headers.origin){
    res.writeHead(200, {
      "Content-Type": "text/html; charset=UTF-8",
      "Access-Control-Allow-Origin":'http://127.0.0.1:8888'
    });
    let user= {
      userName: 'Jack',
      password: '123456'
    }
    res.end(JSON.stringify(user));
  }
})

这里解释一下:当浏览器发现发了跨域请求就会在请求头里添加 Origin: 当前域 字段。服务器此时会检测是否存在 Origin 字段,如果存在那么会在响应头里添加 Access-Control-Allow-Origin: Origin 的值 再返回 JSON 格式结果就行了。前端收到响应后,浏览器会检查 Access-Control-Allow-Origin 的值是否和当前的地址相同,如果相同才能获取到数据。

postMessage

这个方法主要是在前端完成的。在发送请求方只需要调用新 API 的 postMessage 函数就可以了。

postMessage('要发送的消息', '目的地地址', '当前地址')

在接受方要在 window 上监听一个 message 事件。

function receiveMessage(event) {
  // 对发送者做检查 ,如果不是自己人就不返回
  if (event.origin !== "http://example.com:8080")
    return;

  // 这里可以打印发送方的消息
  console.log(event.data)

  // 如果是自己人,就返回数据 
  event.source.postMessage("你好,自己人",event.origin)
}

// 全局监听 `message` 事件
window.addEventListener("message", receiveMessage, false);

这种方法比较简单,但是也要做好发送方的检测。

相关文章

  • HTTP: 跨域真的有这么难吗

    前言 以前写前端小项目的时候就听说过跨域这个词,什么 JSONP啊,CORS啊。感觉很高级,但是无奈项目太小没机会...

  • 2020面试总结

    (一)、跨域理解及HTTP与HTTPS区别,为啥HTTPS比HTTP更安全些? 解决跨域的有JsonP:(只要发送...

  • Http访问跨域解决

    一、跨域科普 跨域,即跨站HTTP请求(Cross-site HTTP request),指发起请求的资源所在域不...

  • ajax

    ajax 跨域 跨域:http 协议 域名 端口 三者只要有一个不同,就是跨域 服务端解决跨域: res.setH...

  • 跨域

    参考资料 HTTP访问控制(CORS)跨域解决方案跨域详解

  • Nodejs 设置跨域

    设置允许所有域名跨域: 设置允许指定域名“http://www.tefang.cn”跨域: 设置允许多个域名跨域:...

  • HTTP跨域

    1.什么是跨域? 有浏览器同源策略限制的一类请求场景,当不同地址、不同端口、不同级别、不同协议就会构成跨域。 如图...

  • Ajax 请求和跨域

    跨域的几种方式: cors方式 cross-orign-resource-shareing(跨域)参考:http:...

  • 前端跨域的理解和解决方案(较全面)

    何为跨域? 首先,我们得先理解一下何为跨域?所谓跨域,即网站的协议名 protocol(例如 http ://) ...

  • HTTP跨域详解

    HTTP支持跨域 HTTP网络中的跨域指的是不同的Host之间的通信,IP(域名)+端口就指定一个域;这几天处理了...

网友评论

    本文标题:HTTP: 跨域真的有这么难吗

    本文链接:https://www.haomeiwen.com/subject/dblxsqtx.html