由于浏览器的同源策略,不同协议、域名、端口的网页是不允许互相请求资源的。但在前后端分离的开发模式中,前后端的域名是不一样的,如果要进行数据的交互就会产生跨域。
解决跨域的方案:
一:cors设置请求头
浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制
-
CORS
主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS
的接口 -
CORS
在浏览器中有兼容性。只有支持XMLHttpRequest Level2
的浏览器,才能正常访问开启了CORS
的服务端接口(例如:IE10+
、Chrome4+
、FireFox3.5+
)
- cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题
- 使用步骤
- 安装中间件:
npm install cors
- 导入中间件:
const cors = require('cors')
- 配置中间件: 在路由之前调用
app.use(cors())
- 安装中间件:
- 示例代码
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 导入中间件
const cors = require('cors')
// 配置中间件
app.use(cors())
// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
// 挂载一个路由
app.post('/test', (req, res) => {
res.send(req.body)
})
// 调用 app.listen 方法,指定端口号并启动 web 服务器
app.listen(3000, () => {
console.log('serve is running')
})
二:JSONP请求
- 浏览器端通过
<script>
标签的src
属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做JSONP
。
JSONP的特点是,它不属于真正的ajax请求,因为它并没有使用XMLHTTPRequest这个对象。但它有很大的局限性,它仅支持GET
请求,不支持POST
、PUT
、DELETE
等请求
2.实现步骤分析
(1)获取客户端发送过来的回调函数的名字
(2) 得到要通过 JSONP
形式发送给客户端的数据
(3) 根据前两步得到的数据,拼接出一个函数调用的字符串
(4) 把上一步拼接得到的字符串,响应给客户端的 <script>
标签进行解析执行
3.示例代码
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
// 必须在配置 cors 中间件之前,配置 JSONP 的接口
app.get('/api/jsonp', (req, res) => {
// 定义 JSONP 接口具体的实现过程
// 1. 得到函数的名称
const funcName = req.query.callback
// 2. 定义要发送到客户端的数据对象
const data = { name: 'zs', age: 11 }
// 3. 拼接处一个函数的调用
const scriptStr = `${funcName}(${JSON.stringify(data)})`
// 4. 把拼接的字符串,响应给客户端
res.send(scriptStr)
})
// 导入中间件
const cors = require('cors')
app.use(cors())
// 挂载一个路由
app.post('/test', (req, res) => {
res.send(req.body)
})
// 调用 app.listen 方法,指定端口号并启动 web 服务器
app.listen(3000, () => {
console.log('running……')
})
注意
如果项目中已经配置了 CORS
跨域资源共享,为了防止冲突,必须在配置 CORS
中间件之前声明 JSONP
的接口,否则 JSONP
接口会被处理成开启了 CORS
的接口