vuecli3开发模式431header过大问题解决方法
最近项目中加入了权限控制,使用了jwt的token,导致header过长,接口直接报431的错误由于后台是nginx做的代理,所以在nginx中做了配置:client_header_buffer_size 16k;large_client_header_buffers 4 16k;但是我们前端本地启动开发环境已经用proxy做了代理了,难道还要用nginx再次本地代理一次吗?坚决不!于是便着手改造
·
最近项目中加入了权限控制,使用了jwt的token,导致header过长,接口直接报431的错误
由于后台是nginx做的代理,所以在nginx中做了配置:
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
但是我们前端本地启动开发环境已经用proxy做了代理了,难道还要用nginx再次本地代理一次吗?坚决不!
于是便着手改造dev的请求头大小限制,一路艰辛啊~
- 顺藤摸瓜,找到启动服务的依赖项
查看package.json中的serve脚本
知道了是vue-cli-service这个包,而这个包在下面的devDependencies中也有
顺藤摸瓜,在node_modules
中找到cli-service包 - 找到cli-service的启动依赖项
由于是用命令npm run serve
的,所以应该查看cli-service中package.json的bin命令指向文件
原来是在bin文件下,进入并打开vue-cli-service.js文件 - 找到
npm run serve
对应的执行文件
一行行读,发现最后是会执行serivce.run这个方法的,并且传参还有command,看来是这个没错了,接着往上看,发现Service类来自lib下的Service,转战lib/Service.js
分析下Service这个类
module.exports = class Service {
constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) {
process.VUE_CLI_SERVICE = this
this.initialized = false
this.context = context
this.inlineOptions = inlineOptions
this.webpackChainFns = []
this.webpackRawConfigFns = []
this.devServerConfigFns = []
this.commands = {}
this.pkgContext = context
// 获取package.json中的依赖
this.pkg = this.resolvePkg(pkg)
// 如果有内联插件,不使用package.json中找到的插件
// 最终得到的plugins为内置插件+@vue/cli-plugin-*
// {id: 'xxx',apply: require('xxx')}
this.plugins = this.resolvePlugins(plugins, useBuiltIn)
// 解析每个命令使用的默认模式
//{ serve: 'development',
// build: 'production',
// inspect: 'development' }
this.modes = this.plugins.reduce((modes, { apply: { defaultModes }}) => {
return Object.assign(modes, defaultModes)
}, {})
}
// ......
}
干了两件事:
- 获取package.json中的依赖。通过read-pkg这个包读取package.json文件,并以JSON格式返回赋值给this.pkg。
- 初始化相关插件(用loadModule依赖)。相关插件包括:内联插件、package.json中的cli-plugin-*插件。内联插件包含serve、build、inspect等。
- 初始化模式。解析每个命令使用的默认模式,例如serve对应的development,build对应production。
根据resolvePlugins中的buildInPlugins配置项,可以知道serve命令指向的是./commands/serve
文件
- 找到serve.js中的实际启动服务的依赖
找到serve.js后就不进一步探寻原理了,想深究的可以参考这篇文章vue-cli-service 机制
找到serve.js中的serve方法,发现其实是通过webpackDevServer来启动的服务
直奔webpackDevServer中 - 研究webpackDevServer的入口文件lib/Server.js
在webpackDevServer依赖包中的package.json中查找main字段,找到了入口文件lib/Server.js
在其中仔细阅读Server类后,可以发现其实启动服务的方法就在createServer方法中
而由于我们没有开启https,所以最终webpackDevServer启动的方法是用nodejs中的http模块的createServer方法启动了一个express实例
- 修改http模块的maxHeaderSize
查看nodejs的http模块文档,找到http.createServer方法说明文档,喜出望外,居然有现成的参数可以调
通过查看http的代码说明也知道createServer有做重载(模拟的,js无法重载)
二话不说,直接改源码。
将createServer中的参数进行改造
this.listeningApp = http.createServer({maxHeaderSize:4*1024*1024},this.app);
(不可直接用.
进行赋值修改,因为maxHeaderSize只有getter属性,是只读的) - 方法不生效,去官方问
兴高采烈启动npm run serve
,发现还是图样图森破,然并卵
一打印http.maxHeaderSize,发现还是8kb大小
然后在express和node的github上去搜索有没有碰到相同问题的,还真有
看来国外的友人也碰到这个现象了,讨论了一大通后还是没啥结论,感觉可能是官方bug - nodejs 14版本带来转机
无奈只能再去翻翻官方文档了
还是看到了http.createServer这个方法,发现了一个意外惊喜
对,没错,14.0+的nodejs版本居然把大小更新到了16kb - 升级nodejs,重装依赖
马上决定进行node升级,由于装了sass依赖,所以也要对应升级node-sass,因为他们的版本号是一一对应的,14+的nodejs无法加载4.14 以下的node-sass
然后直接升级node-sass直接报sass版本不同意要npm rebuild,算了,索性把依赖删了重装 - 成功
重装依赖后再发请求就成功啦,(▽),打印http.maxHeaderSize也是显示16kb了,搞定,不过如果header再大就难办了,但是那么大的header是不是也说明后台的开发同学要反思下了呢?吐舌(ૢ˃ꌂ˂ૢ)
更多推荐
已为社区贡献4条内容
所有评论(0)