[摘录于 不要再问我跨域的问题了](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)简单请求
同时满足以下两大条件,就属于简单请求:
- 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
- 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) {
}
}