(七)之 跨域

78 阅读1分钟

[摘录于 不要再问我跨域的问题了](segmentfault.com/a/119000001…)

一、为什么会有跨域

浏览器的同源策略。
同源:域名、协议、端口都相同。

二、跨域的几种解决方法

1.JSONP

在HTML标签里,一些标签比如script、img这样的获取资源的标签是没有跨域限制的。 只能发送get请求。

  • 简单版前端
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script type="text/javascript">
            // 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,
            // 所以这里能拿到res
            window.jsonpCb = function (res) {
                console.log(res)
            }
        </script>
        <script src="http://localhost:9871/api/jsonp?msg=helloJsonp&cb=jsonCb" type="text/javascript"></script>
    </body>
</html>

2.空iframe➕form

可以发送post请求。

const requestPost = ({url, data}) => {
    // 首先创建一个用来发送数据的iframe
    const iframe = document.createElement('iframe')
    iframe.name = 'iframePost'
    iframe.style.display = 'none'
    document.body.appendChild(iframe)
    const form = document.createElement('form')
    const node = document.createElement('input')
    // 注册iframe的load事件处理程序,如果你需要在响应返回时执行一些操作的话
    iframe.addEventListener('load', function () {
        console.log('post success')
    })
    
    form.action = url
    // 在指定的iframe中执行form
    form.target = iframe.name
    form.method = 'post'
    for (let name in data) {
        node.name = name
        node.value = data[name].toString()
        form.appendChild(node.cloneNode())
    }
    // 表单元素需要添加到主文档中
    form.style.display = 'none'
    document.body.appendChild(form)
    form.submit()
    
    // 表单提交后,就可以删除这个表单,不影响下次的数据发送
    document.body.removeChild(form)
}
// 使用方式
requestPost({
    url: 'http://localhost:9871/api/iframePost',
    data: {
     msg: 'helloIframePost'
    }
})

3.CORS(Cross-origin resource sharing)跨域资源共享

CORS有两种请求,简单请求和非简单请求。
(1)简单请求 同时满足以下两大条件,就属于简单请求:

  1. 请求方法是以下三种方法之一:
  • HEAD
  • GET
  • POST
  1. HTTP的头信息不超出以下几种字段:
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值,application/x-www-form-urlencoded、multipart/form-data、text/plain 代码 后端
// 处理成功失败返回格式的工具
const { successBody } = require('../util')
class CrossDomain {
    static async cors (ctx) {
        
    }
}