前端开发中,跨域是是开发员们常遇到的问题,也是面试中被问到的问题中热度非常高的。面对跨域,我们要正视它,不慌不忙的分析解决它。
什么是跨域
跨域,是指同一个域下的文档或脚本试图去请求另一个域下的资源(这里跨域是广义的)。 那么什么又是广义的跨域和狭义的跨域呢?
广义的跨域:
1. 资源跳转: a标签的超链接、重定向、表单提交
2. 资源嵌入: link、script、img等dom标签
狭义的跨域: 是由浏览器同源策略限制的一类请求场景。而同源策略要求两个服务需要通信遵守同源策略:即同协议 、 同域名 、 同端口。同源 浏览器才会让你发出请求,如果不同源,就产生跨域问题。即:
- http://localhost:8080/index.html
- localhost.com/api/v
- baidu.com
- api.baidu.com
基于Node的普通跨域请求
具体步骤如下:
- 前端设置
let requestHeaders = new Headers();
requestHeaders.append('X-auth', 'dhyaun')
requestHeaders.append('content-type', 'application/json')
fetch('http://localhost:3000/api/getBook', {
method: 'POST',
data:{page: 1},
headers:requestHeaders
})
.then(res => res.json())
.then(data => {
console.log(data)
})
2.后端实例代码:
const http = require('http')
http.createServer((req, res) => {
console.log(req.url, req.method)
// 'Access-Control-Allow-Credentials': true 是否允许 cookie 传输
res.writeHead(200, {
'content-type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'x-auth, content-type',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS',
'Access-Control-Allow-Credentials': true
})
res.end(JSON.stringify({
bookName: 'php'
}))
})
.listen(3000,() => {
console.log('启动成功: http://localhost:3000')
})
jsonP的跨域
何为jsonP: jsonp的整个过程就类似于前端声明好一个函数, 后端返回执行函数。执行函数参数中携带所需的数据。此外,主要是因为link script img 不受同源策略的影响,可以使用这些标签实现跨域。
具体步骤如下:
1.前端设置
<script> function getBook(res) { console.log('得到的结果 :', res) } </script> <!-- 1: script 加载回来的东西 被当作 js 执行 --> <!-- getBook() --> <script src="http://localhost:3000/api/getBook"></script>
2.后端实例代码:
const http = require('http')http.createServer((req, res) => { console.log(req.url, req.method) // 'Access-Control-Allow-Credentials': true 是否允许 cookie 传输 res.writeHead(200, { 'content-type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'x-auth, content-type', 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS', 'Access-Control-Allow-Credentials': true }) // jsonP res.end(` getBook(${JSON.stringify({bookName: 'php'})}) `)}).listen(3000,() => { console.log('启动成功: http://localhost:3000')})