Skip to content

跨域

同源策略

  • 一个请求至少三部分组件: 协议 + 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()
})

代理服务器

image-20230207184131212

全局安装应用生成工具

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 模块转发至目标服务器
  1. 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))
  1. 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)
})