nginx导致vue设置history模式下的请求丢失参数

您所在的位置:网站首页 vue路由跳转参数丢失 nginx导致vue设置history模式下的请求丢失参数

nginx导致vue设置history模式下的请求丢失参数

2024-03-11 16:21| 来源: 网络整理| 查看: 265

nginx导致vue设置history模式下的请求丢失参数

问题描述:

当访问下面的路径时参数会丢失:

http://ip/vuecay/path1/path2?name=cay

演示效果:

在这里插入图片描述

可以看到地址栏会发生变化,参数name=cay丢失,页面也没获取到参数的内容,请求也发生了301重定向。

上面是对情况的说明,接下来演示复现参数丢失的过程。

复现history模式请求丢参数的情景

vue相关的代码和nginx的日志格式都放在附录里了。

首先vue的模式设置为history:

mode: 'history'

接着设置location(有问题的):

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

访问路径:

http://ip/vuecay/path1/path2?name=cay

访问截图:

在这里插入图片描述

nginx访问日志(只展示重点的信息):

第一次请求发生了301

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:22:42:34 +0800] – request:"GET /vuecay/path1/path2?name=cay HTTP/1.1" – status:301 – body_bytes_sent:162 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay – args: – is_args: – request_body:- – query_string:

重定向后的请求

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:22:42:34 +0800] – request:“GET /vuecay/ HTTP/1.1” – status:200 – body_bytes_sent:583 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay/index.html – args:- – is_args: – request_body:- – query_string:-

从截图中可以看到地址栏发生改变,参数丢失,第一次请求会发生301重定向,第二次请求地址发生改变,页面也没获取到参数。

从nginx日志可以看出两次请求的高亮的部分的request和uri都有很大的变化,但是args(第二次多了‘-’)和is_args没什么变化

修改nginx配置解决参数丢失

上面的location的try_files的配置会导致history模式下的请求参数丢失:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

改用这个location的try_files的配置就不会参数就丢失了。

主要的变化是try_files最后面的vuecay的后面多了一个‘/’

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html。 #vuecay后面有‘/index.html’,等同于“/”,vuecay后面有“/”会自动在“/”后面添加index.html try_files $uri $uri/ /vuecay/index.html; } #这两个loction是一样的 location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html。 #vuecay后面有‘/index.html’,等同于“/”,vuecay后面有“/”会自动在“/”后面添加index.html #index.html可以不加,但是vuecay必须有‘/’ try_files $uri $uri/ /vuecay/; }

使用上面的访问路径:

http://ip/vuecay/path1/path2?name=cay

访问截图:

在这里插入图片描述

nginx访问日志(只展示重点信息):

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:23:01:24 +0800] – request:“GET /vuecay/path1/path2?name=cay HTTP/1.1” – status:200 – body_bytes_sent:583 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay/index.html – args: – is_args: – request_body:- – query_string:

从截图可以看出来,地址栏未发生变化,正常显示参数,请求不会发生301,页面正常显示获取的参数。

从nginx的访问日志来看确实也没有请求发生301,和上面loction发生301之后的请求相比,args后面没有‘-’,is_args没有变化。但是和我的预期不符合,request的请求路径里有参数(和下面hash解决参数的request后面的请求路径做对比),所以我以为args后面会有值,is_args也会有值(有值的情况可以看下面的拓展),但是两个都没有值,这是疑惑点,待解决。

总的来说,在vuecay后面添加‘/’,确实可以解决丢参数的问题。

对比两种情形的location配置

history模式丢参数的location中的try_files配置:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

history模式不丢参数的location中的try_files配置:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html。 #vuecay后面有‘/index.html’,等同于“/”,vuecay后面有“/”会自动在“/”后面添加index.html try_files $uri $uri/ /vuecay/index.html; }

两者最大的区别是try_files最后面的vuecay是有带有了“/”。如果vuecay后面没带“/”代表的是资源,vuecay后面带“/”代表的是vuecay目录下的index.html。

丢参数的location的try_files里的

$uri$uri//vuecay

这三个配置是一样的意思。网上有人说$uri/是为了访问uri对应目录下的资源,但是测试中并不会自动查找index.html,当我手动添加index.html,才会去查找uri目录下的index.html。

大家可以试试这个location:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 # $uri/后面添加index.html try_files $uri $uri/index.html /vuecay; }

测试结果和$uri/后面没有index.html完全不同。

不丢参数的location的try_files里配置的是 /vuecay/index.html ,等价于/vuecay/,这里后面会自动添加index.html。而$uri/后面却 不会自动添加index.html,很奇怪。

hash模式解决参数丢失 mode: 'hash'

history模式丢参数的location的try_files的配置

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

访问路径:

http://ip/vuecay/#/path1/path2?name=cay

访问截图:

在这里插入图片描述

nginx访问日志(只展示重点):

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:23:47:32 +0800] – request:“GET /vuecay/ HTTP/1.1” – status:200 – body_bytes_sent:583 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay/index.html – args:- – is_args: – request_body:- – query_string:-

从截图可以看出地址栏也未变化,参数未丢失,页面正常显示参数,请求未发生301,也解决了参数丢失。从nginx访问日志看出,args和is_args还是没有值。这里的request后面的请求路径没有参数,args和is_args没有值我还能理解,但是上面的request后面的请求路径有参数,args和is_args还没有值,真是令人头大。拓展的一级路径里args和is_args都有值,这就很无语,看来还得好好看看,后续明白了会再更新。 history丢参数,hash模式不丢参数的原因

因为nginx默认是支持hash模式的,不像history模式还得额外配置try_files。而且这里的location是出现问题的try_files的配置,所以history模式受影响,hash模式不受影响,即history模式会丢参数,hash模式不丢参数。

想要了解更多的信息nginx配置导致301的信息,可以看一下我写的另一篇文章:nginx配置导致的301和丢参数的问题的关系

拓展:一级路径不丢参数

上面使用的是三级路径(ip后面跟了三层目录/vuecay/path1/path2,我这里暂且称为三级路径):

http://ip/vuecay/path1/path2?name=cay

通过测试发现二级及以上路径,在vue为history模式并且错误的try_files配置中会丢失参数,但是一级路径却不会丢失参数

vue的模式设置为history:

mode: 'history'

history模式丢参数的location的try_files的配置:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

测试的一级路径:

http://ip/vuecay?name=cay

访问截图:

在这里插入图片描述

nginx访问日志:

请求发生301

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:23:20:27 +0800] – request:“GET /vuecay?name=cay HTTP/1.1” – status:301 – body_bytes_sent:162 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay – args:name=cay – is_args:? – request_body:- – query_string:name=cay

重定向后的请求

remote_addr:111.196.243.20 – remote_user:- – time_local:[25/Jul/2022:23:20:27 +0800] – request:“GET /vuecay/?name=cay HTTP/1.1” – status:200 – body_bytes_sent:583 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay/index.html – args:name=cay – is_args:? – request_body:- – query_string:name=cay

从截图可以看出来,地址栏发生变化(vuecay多了“/”),参数未丢失,请求会发生301,这是因为vuecay后面没有‘/’,所以发生301。这里和上面的三级路径的测试的最大区别是参数没有丢失。从nginx的访问日志可以看出,无论在发生301的那次请求中,还是301重定向之后的请求,args和is_args都是有值。

可见一级路径在错误的配置下,发生了301,但是却没有丢失参数,但是如果是二级路径及以上则会丢失参数,感兴趣可以尝试。(具体原因还待深入研究)

测试hash模式:

我主要想看args和is_args是否有值

mode: 'hash'

访问路径:

http://ip/vuecay/#/?name=cay

location的设置:

location /vuecay { root html; index index.html index.htm; # 匹配history模式,histoty模式必须要配置,hash模式可以不用配置 #这里有两个坑:$uri/后面没有index.html,后面不会自动添加index.html,vuecay后面没有‘/’ try_files $uri $uri/ /vuecay; }

访问截图:

在这里插入图片描述

nginx访问日志:

remote_addr:111.196.243.20 – remote_user:- – time_local:[26/Jul/2022:00:03:06 +0800] – request:“GET /vuecay/ HTTP/1.1” – status:200 – body_bytes_sent:583 – http_referer:“-” – http_user_agent:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36” – http_x_forwarded_for:“-” – uri:/vuecay/index.html – args:- – is_args: – request_body:- – query_string:-

从截图可以看出地址栏正常,参数未丢失,内容正常显示参数,未发生301重定向从nginx日志来看,args和is_args没有值。和上面三级路径的hash模式一样都没有值。

综上,我感觉args和is_args不能作为参数丢失的依据,和我最初的设想不一样。。。

小结 try_files的错误配置会导致history模式下的请求的参数丢失,将try_files修改正确即可不丢失参数。hash模式不需要额外配置try_files,所以不会丢失参数。nginx配置的时候注意“/”,有“/” (目录下的资源,一般是index.html)和 无“/” (资源)是两种含义。try_files中的$uri/ 虽然带有“/”,但是后面默认不带index.html,所以最好自己添加index.html。一级路径在vue是history模式,try_files配置有问题的情况下,不会丢失参数。我感觉args和is_args不能作为参数丢失的依据(疑惑待解决)。

高亮的两条总结,是这次history请求丢参数的主要误区,大家一定要注意。如果大家测试的结果和我不同,欢迎一起讨论。

想要了解更多的信息nginx配置导致301的信息,可以看一下我写的另一篇文章:nginx配置导致的301和丢参数的问题的关系

附录:nginx的日期格式 log_format main 'remote_addr:$remote_addr -- remote_user:$remote_user -- time_local:[$time_local] -- request:"$request" ' '-- status:$status -- body_bytes_sent:$body_bytes_sent -- http_referer:"$http_referer" ' '-- http_user_agent:"$http_user_agent" -- http_x_forwarded_for:"$http_x_forwarded_for" -- uri:$uri -- args:$args ' '-- is_args:$is_args -- request_body:$request_body -- query_string:$query_string'; 附录:vue代码

我们构建简单的vue项目,使用路由,vue的相关代码如下。

Route.js

import VueRouter from "vue-router" import HelloWorld1 from "./components/HelloWorld1" import HelloWorld2 from "./components/HelloWorld2" import HomeTest from "./components/HomeTest" export default new VueRouter({ mode: 'hash', base: '/vuecay/', deep: true, routes: [{ //一级目录需要添加‘/’ path: '/', component: HomeTest, //redirect: "/path1/path2", children: [{ path: 'path1', component: HelloWorld1, children: [{ //二级目录不需要加‘/’ path: 'path2', component: HelloWorld2 } ] } ] } ] })

Vue.config.js

const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, publicPath: '/vuecay/' })

Main.js

import Vue from 'vue' import App from './App.vue' import VueRouter from "vue-router" import router from '@/router' Vue.config.productionTip = false Vue.use(VueRouter) new Vue({ render: h => h(App), router }).$mount('#app')

App.vue

//import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', }

HomeTest.vue

//import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', }

HelloWorld1.vue

welcome to path1,{{name}},访问的路径的参数:{{argName}} export default { name: 'HelloWorld1', data(){ return { name: 'cay', argName: '' } }, props: { msg: String }, created () { console.log('path1:' + window.location.href) console.log('path1:' + this.$route.query.name) console.log(this.$route) console.log(this.$router) this.argName = this.$route.query.name } }

HelloWorld2.vue

welcome to path2,{{name}},访问的路径的参数:{{argName}} export default { name: 'HelloWorld2', data(){ return { name: 'lucy', argName: '' } }, props: { msg: String }, created () { console.log('path2:' + window.location.href) console.log('path2:' + this.$route.query.name) console.log(this.$route) console.log(this.$router) this.argName = this.$route.query.name //const x = { a: 8 }; //console.log(JSON.stringify(x)) } }

执行命令

npm run build

将编译后的文件部署到服务器上。部署的时候惨过一些坑后面会总结贴上链接。上面的步骤已经是排除坑之后的步骤了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3