1.vue项目打包发测后,访问项目链接,功能未生效,刷新后才生效。

  • 首先,查看两次访问,获取到的文件是否相同。查看network,两次访问请求如下,可见两次获取到的app.js不是同一个文件。开始认为是浏览器缓存问题,查看如下资料知悉跟浏览器缓存无关。(浏览器缓存

clipboard.png
clipboard.png

  • 其次,查看app.js文件是否加了hash。在build/webpack.prod.conf.js中看到js文件加了chunkhash,css文件加了contenthash,js、css缓存没问题。(webpack三种hash区别

clipboard.png
clipboard.png

  • 最后,排查index.html文件是否缓存,看到html文件中app.js文件还是引入的旧的hash文件。

clipboard.png

  • 解决方案:由于服务器缓存问题,有缓存是因为index.html被缓存了,导致浏览器不去加载最新的js,解决方法是让运维配置下去掉index.html的缓存。(缓存问题讨论

2.在vue中使用jsx

npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props --save
//在.babelrc配置
{
  "presets": ["@vue/app","@vue/babel-preset-jsx"]
}

报错:Duplicate declaration "h" (This is an error on an internal node. Probably an internal error.)
解决方法

//在.babelrc配置,删掉"@vue/babel-preset-jsx"
{
  "presets": ["@vue/app"]
}

3.webpack代理问题排查

  • 问题描述:vue-cli3构建的项目,本地开发环境通过webpack中的devserver代理请求到后端服务,接口A返回如下两种情况,其他接口均正常。但通过浏览器url直接访问后端服务接口A,接口返回200,是可以拿到全部数据的。
Proxy error: Could not proxy request /xxx/list?pageNo=1&pageSize=10 from localhost:8080 to http://x.x.x.x:8108 (ECONNRESET).

{"code":"200","msg":"请求成功","success":true,"data":{"total":107,"list":[{...},...,{"id":132,..."name":"账户�Proxy error: Could not proxy request /eventNotifyPerson/list?pageNo=1&pageSize=10 from localhost:8080 to http://172.16.21.237:8108 (ECONNRESET).
  • 查看Node.js Error中详细解释:
ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the http and net modules.
  • 问题排查:

    • 确定是否数据有异常:让后端在数据库里删掉id为132的这条数据,发现问题仍然存在;
    • 确定是否前端代理有问题:后端将程序发布到dev环境,前端代理不变,接口返回200,数据正常。
    • 后端问题排查,wireshark抓包发现http传输,数据包没传输完,连接就断开了。

      • 尝试在前端请求头中加Connection: Keep-Alive。一开始尝试在axios请求中加,添加方式如下:

        axios.defaults.headers['Connection'] = 'Keep-Alive'

        控制台报错:[图片]
        clipboard.png
        换另外一种方式:[图片]
        clipboard.png
        浏览器看到是:Connection: Keep-Alive
        clipboard.png
        但抓包中显示:connection: close,难道是加的不对,没生效?又参考(axios的api文档),在接口的config中添加,结果还是一样。
        clipboard.png
        查找资料HTTP Keep-Alive模式,发现浏览器keep-alive机制如下:
        clipboard.png
        查看抓包中的http请求是1.1版本,理应会是默认开启keep-alive的,随后找后端确认,原来虽然浏览器发出的时候,keep-alive是默认开启的,但经过webpack的代理转发,keep-alive被关闭了,代理将这个值设置为了close,随后查找资料,深入分析vue的webpack代理设置:vue.config.js中的devServer.proxy实际使用的是http-proxy-middleware中间件,查看配置项,修改devServer如下:
        clipboard.png
        查看wireshark抓包内容,确认proxy的Connection: Keep-Alive,添加成功。
        clipboard.png
        再次访问后端接口,接口200,数据正常,问题修复。

      • 初步结论:浏览器会默认开启keep-alive,所以通过浏览器url访问可以拿到全部数据,但是经过webpack的代理转发,keep-alive被关掉了,要在这里设置开启。在接口返回数据量很大的时候,会遇到这种问题。
      • 问题反思,虽然这样接口正常了,但是在开发其他项目的时候,数据量有比这个更大的,在proxy中从来没有加过keep-alive。
      • 再次确认是否是后端问题:后端把服务部署到本地的tomcat下,前端代理不加keep-alive,接口返回200,数据正常。
      • 最终结论:原来后端服务是部署在jetty下,dev环境是部署在tomcat下(听后端专家说:jetty提供的数据包保存在内存中,发送给前端,包还没发完,就被jetty给关掉了,导致抓包中数据丢失;而tomcat会保证数据数据全部发送给前端,所以dev环境正常),所以会出现访问后端本地,接口500,访问dev环境接口200,最终确认是后端jetty配置问题导致。

Andy
5 声望2 粉丝

前端工程师