跨域
同源策略
一个请求至少三部分组件: 协议 + IP + 端口。
同源策略是浏览器的安全策略,他要求协议 + IP + 端口三者都必须一致,则为同源。
当我们在一个页面中,向服务器发送其他请求时,页面地址和请求地址,协议,IP,端口三者不一致则为跨域
跨域解决方案
- JSONP
- CORS
- 代理服务器
JSONP
js
// 前端
$.ajax({
method: 'get',
url: '/classes',
dataType: 'jsonp', // 解决跨域
success(msg) {},
})
js
// 后端
router.get('/', async function (req, res, next) {
const data = await getClasses()
res.jsonp(data) // 解决跨域
})
缺点:只能解决 get 请求类型的跨域。
CORS
插件
cors 是 Express 的一个第三方中间件,通过安装和配置 cors 中间件,可以很方便地解决跨域问题
使用步骤分为三步
- 运行
npm install cors
安装中间件 - 使用
const cors = require('cors')
导入中间件 - 在路由之前调用
app.use(cors())
配置中间件
代码
js
//设置CORS
app.all('*', function (req, res, next) {
//当允许携带cookies此处的白名单不能写’*’
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
//允许的请求头
res.header(
'Access-Control-Allow-Headers',
'X-Requested-With,Content-Type, Origin,Accept,Authorization'
)
//允许的请求方法
res.header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT')
//允许携带cookies
res.header('Access-Control-Allow-Credentials', true)
next()
})
代理服务器
全局安装应用生成工具
bash
npm i express-generator -g
1.创建代理服务器
以下命令,在指定目录中创建项目
bash
express 项目名
2.安装依赖
bash
// 进入项目
cd 项目名
// 安装依赖
npm install
3.安装中间层
代理服务器作为客户端和目标服务器之间的中间层,当客户端将请求发送到代理服务器后,代理服务器需要借助http-proxy-middleware
中间件,在把请求代理转发到目标服务器
bash
npm i http-proxy-middleware
4.修改服务器端口
代理服务器和目标服务器的端口不能相同,代理服务器端口在bin/www
文件中修改
5.配置请求转发
将代理服务器中的请求转发到目标服务器,两种方式:
- 在代理服务器中接收到请求后,通过
http-proxy-middleware
中间件直接转发至目标服务器 - 在代理服务器中接收到请求后,完成一些额外的操作(例如密码加密处理)在通过
request-promise
模块转发至目标服务器
- http-proxy-middleware 转发
找到项目应用根目录中的
app.js
文件,在该文件中引入http-proxy-middleware
js
const { createProxyMiddleware } = require('http-proxy-middleware')
const option = {
// 目标服务器
target: 'http://localhost:3000',
// 默认 false 是否需要改变原始主机头为目标 URL
changeOrigin: true,
// 重写请求
pathRewrite: {
// 所有以 '/api'开头的请求,会重写为 '/'
'^/api': '/',
},
}
var app = express()
// 这行必须在express下面 proxy(options)即创建代理
app.use('/api', createProxyMiddleware(option))
- request-promise 转发
虽然客户端的大部分请求我们都可以通过代理服务器 http-proxy-middleware
中间件转发至目标服务器,但是类似于登录注册这种特殊请求,我们需要先在代理服务器处理(例如密码加密),然后发送到目标服务器,那么这个时候http-proxy-middleware
中间件的自动转发就不可用了
因此这种情况下我们选择另一种模块--request-promise
来处理我们的请求转发
安装依赖
bash
npm i request request-promise
什么地方使用就调用
js
const rp = require('request-promise')
router.post('/login', async (req, res, next) => {
// 。。。进行密码加密操作
const data = await rp({
method: 'post',
uri: 'http://localhost:3000/users/login',
body: req.body,
json: true,
})
res.send(data)
})