node代理解决本地开发跨域问题
背景
跨域:指的是浏览器不能执行其它网站的脚本。它是由浏览器的同源策源引起的,是浏览器对
JavaScript
施加的安全限制。
在前后分离的开发过程中,由于静态资源在本地,而api接口在另一台服务上,我们经常会使用localhost
或者IP的方式去访问另一台服务器的api接口,这就会产生跨域问题。
对于由webpack
构建的项目在开发环境解决跨域很方便,直接修改webpack
的代理配置就可以。而对于一些由jq
构建或者原生的项目则无法通过这种方式解决。本文记录一下如何通过node
启动一个代理服务解决这类项目的开发环境跨域问题。
准备工作
首先我们先来创建一个jq
项目,项目包含html
和页面加载的css
,js
,html
内通过ajax
访问接口。
let baseUrl = "http://localhost:8082"
function getList() {
$.ajax({
type: "post",
headers: {
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "b889e2f9-9720-4d93-a798-f63e9cbfd7f0"
},
url: baseUrl + "/api/getList",
data: JSON.stringify({ "pageNum": 1, "pageSize": 10, "type": 0 }),
dataType: "json",
success: res => {
console.log(res)
}
})
}
getList()
这里模拟了一下项目里的ajax
配置,携带了验权信息以及参数,我将后端的api服务
运行在本地的8082
端口上,不同环境的api地址
可以修改baseUrl
。这时候打开index.html
发现页面抛出了一个跨域错误,至此,我们就模拟出了一个跨域的jq项目。
手撸代码
1.创建node项目
环境基于 node: v12.13.1、 webpack: v3.6.0
在jq-project
的同级目录下执行npm init
命令,一路回车,会得到一个默认配置的package.json
文件:
{
"name": "init",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
同级目录下创建index.js
文件名要与package.json
中的main
指向的文件名一致,安装express
和nodemon
插件,创建一个简单的node
服务监听3000
端口。
npm i express nodemon
express
是一个node.js Web框架
,可以使项目更轻快灵活;nodemon
是一个实现node.js
热更新的插件,保存时就可以更新js文件;
let express = require('express');
let app = express()
app.listen(3000,()=>{
console.log("server running at http://localhost:3000")
})
在package.json
添加一条启动命令,npm start
启动服务,控制台输出server running at http://localhost:3000
即为启动成功。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
2.通过node服务访问html
将jq-project
下的静态资源通过express
托管,这样通过http://localhost:3000/index.html
就可以访问到jq-project
下的资源。
app.use('/', express.static('jq-project'))
-
express.static(root, [options])
是express
内置的中间件,可以托管静态资源.如:1.
app.use('/', express.static('jq-project'))
可以通过http://localhost:3000/index.html
、http://localhost:3000/js/jquery.min.js
访问到资源。2.
app.use('/static', express.static('jq-project'))
可以通过http://localhost:3000/static/index.html
、http://localhost:3000/static/js/jquery.min.js
访问到资源。
3.配置代理
http-proxy-middleware
是一个实现代理的中间件。webpack
也是使用这个插件实现代理的,所以它的配置跟webpack代理
配置一致。
代理原理示意:
npm i http-proxy-middleware
let express = require('express');
let app = express()
let { createProxyMiddleware } = require('http-proxy-middleware');
const options = {
target: 'http://localhost:8082',
changeOrigin: true,
ws: true,
secure: true,
pathRewrite: {
'/api': '/api',
},
};
app.use('/', express.static('jq-project'))
app.use('/api', createProxyMiddleware(options));
app.listen(3000,()=>{
console.log("server running at http://localhost:3000'")
})
target
:要代理到的服务器,可以是域名也可以是ip+端口号;changeOrigin
:虚拟托管网站,如果为true
,8082端口服务端获取的请求headers
中请求来源是3000端口服务器.如果为false
,获取的请求headers
中请求来源是8082端口服务器;ws
:是否代理websockets
;secure
:是否代理https请求;pathRewrite
:重写路径,将":"前的路径替换为后面的路径;
4.请求代理服务
修改html
中的ajax
请求,将请求的url改为代理服务器。刷新页面,成功的拿到数据。
baseUrl = "http://localhost:3000"


结尾
解决跨域的方法有很多,这种方式是我比较热衷的一种方式,几行代码就可以实现,也不用麻烦后端或者运维去修改服务器的配置,自给自足。当有新的项目只需要再声明一个代理就可以,十分方便。
转载自:https://juejin.cn/post/7001894700596592653