前端vue打包到服务器后,发现在前端的代码中的重定向失效,比如没有token时候访问资源要重定向到login页面,放到服务器上就直接nginx404,不跳转,然后通过配置nginx解决问题:
下文大部分来自转载,已经标记来源 ,有问题可以联系删除
nginx具体配置信息可以看写给前端同学的Nginx配置指南
写的挺全的
这里主要说解决重定向:
(一)配置 try_files 实现内部重定向
部分摘自Nginx:配置 try_files 实现内部重定向_Java Punk的博客-CSDN博客
Nginx的配置语法灵活,可控制度非常高。
在0.7以后的版本中加入了一个try_files指令,配合命名location,可以部分替代原本常用的rewrite配置方式,提高解析效率。
1、try_files指令介绍
语法:try_files file ... uri(格式1) 或 try_files file ... = code(格式2)
默认值:无
作用域:server location
解释说明:
- 按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理;
- 查找路径是按照给定的root或alias为根路径来查找的;
- 如果给出的file都没有匹配到,则会进行一个内部重定向到最后一个参数给定的uri,就是新的location匹配;
- 只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向;
- 最后一个参数是回退URI且必须存在,否则会出现内部500错误;
- 如果是(格式2),若最后一个参数是 = 404 ,若给出的file都没有匹配到,则最后返回404的响应码。
2、举例说明
例1:
- root 后面的参数是前端vue项目代码安装目录;
- try_files 负责扫描内部目录然后再进行内部重定向;
- expires 是nginx控制缓存的一种方式,7d=7天。
location / {
root /home/nx/dist;
try_files $uri $uri/ /index.php?$query_string
expires 7d;
}
当用户请求 http://localhost/example
时,这里的 $uri
就是 /example
,try_files 会到硬盘里尝试找这个文件;
如果存在名为 /$root/example
(其中 $root
是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户;
显然,目录中没有叫 example
的文件;
然后就看 $uri/
,增加了一个 /
,也就是看有没有名为 /$root/example/
的目录;
又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php
,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php
。
例2:
location / {
try_files /app/cache/ $uri @fallback;
index index.php index.html;
}location @fallback {
rewrite ^/(.*)$ http://www.baidu.com # 跳转到百度
}
它将检测$document_root/app/cache/index.php,$document_root/app/cache/index.html 和 $document_root$uri是否存在,如果不存在着内部重定向到 @fallback。
@表示配置文件中预定义标记点,如上所示(@fallback)。
你也可以使用一个文件或者状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在。
3、我遇到的问题
小编通过nginx启动vue以后,我们在访问页面的时候只能访问默认页面和通过项目内跳转其他页面,如果刷新就会404。如图:
关于单页面,刷新404问题,如vue + nginx的配置, vue路由必须先加载 index.html 或者XX.js 才能识别到路由,故直接刷新页面会出现404。
这时候最好到做法,是使用try_files 进行尝试,如果获取不到资源,加载index.html 再利用 rewrite的 last参数,保持路由路径不变,从而实现刷新页面。
但需要注意:此种解决方法需要 vue和nginx部署在同一台服务器上,这样try_files才能在服务器硬盘上找到index.html文件。
原来的nginx配置:
location / {
root /home/vue/dist;
index index.html index.htm index.jsp;
}
修改后的nginx配置:
将默认的index注释掉,换成了try_files,它会去扫描内部目录然后再进行内部重定向,规则上面介绍过了。
location / {
root /home/nx/dist;
#index index.html index.htm index.jsp;
try_files $uri $uri/ /index.html;
expires 7d;
}
(二)用return 和rewrite实现重定向
摘自
当需要将某个URL地址重定向到另外一个URL地址时,我们就需要使用重定向功能。Nginx是一款高效的Web服务器,它提供了多种重定向方法。本文将详解Nginx中的重定向功能,希望对你有所帮助。
一、Nginx中的重定向
1. 什么是重定向
重定向指的是当用户访问某个URL时,服务器将该URL重定向到另外一个URL的过程。重定向可以帮助我们更好的管理网站内容,优化SEO效果,提升用户体验等。Nginx中提供了多种重定向方式,包括301重定向、302重定向、rewrite重定向等。
2. 301重定向
301重定向是一种永久性的重定向方式,当用户访问某个URL时,服务器会将该URL重定向到另外一个URL,并且告诉浏览器该URL已被永久性的移动到了新的URL。301重定向对于SEO优化非常有利。例如,我们要将http://example.com
重定向到https://example.com
,可以在Nginx的配置文件中添加如下代码:
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
3. 302重定向
302重定向是一种暂时的重定向方式,当用户访问某个URL时,服务器会将该URL重定向到另外一个URL,并且告诉浏览器该URL只是临时性的移动到了新的URL。302重定向对于一些临时性的网站内容重定向非常有用。例如,我们要将http://example.com
重定向到http://www.example.com
,可以在Nginx的配置文件中添加如下代码:
server {
listen 80;
server_name example.com;
return 302 http://www.example.com$request_uri;
}
4. rewrite重定向
rewrite重定向是一种通过Nginx的rewrite模块实现的URL重定向方式,它可以将请求URL重写为另外一个URL,支持正则表达式匹配等高级功能。例如,我们要将http://example.com/dir1/page1.html
重定向到http://example.com/dir2/page2.html
,可以在Nginx的配置文件中添加如下代码:
server {
listen 80;
server_name example.com;
rewrite ^/dir1/page1.html$ /dir2/page2.html permanent;
}
二、示例说明
1. 301重定向示例
假设我们现在要将http://www.example.com
重定向到https://www.example.com
,可以在Nginx的配置文件中添加如下代码:
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
# SSL/TLS相关配置
# ...
}
在以上配置中,首先对http://www.example.com
进行301重定向,将其重定向到https://www.example.com$request_uri
。而https://www.example.com
的相关HTTPS配置则需要额外配置。
2. rewrite重定向示例
假设我们现在有一个请求URL为http://www.example.com/article/1234.html
,我们想要将其重定向到https://www.example.com/article/1234.htm
,则可以在Nginx的配置文件中添加如下代码:
server {
listen 80;
server_name www.example.com;
rewrite ^/article/(\d+)\.html$ https://www.example.com/article/$1.htm permanent;
}
server {
listen 443 ssl;
server_name www.example.com;
# SSL/TLS相关配置
# ...
}
在以上配置中,首先使用rewrite模块将http://www.example.com/article/1234.html
重定向到https://www.example.com/article/1234.htm
,其中\d+
是一个正则表达式,用来匹配1234这个数字;而$1
则代表正则表达式匹配的结果。而https://www.example.com
的相关HTTPS配置同样需要额外配置。
以上就是本文对Nginx中的重定向功能的详解,希望能对大家有所帮助。
(三)Nginx & 详细举例 location -> index、return、rewrite、try_files、alias 各个属性的含义、注意事项和区别
1、准备工作
1.1 本案例以 centos7 系统作为演示,配置文件在 /etc/nginx/conf.d/test.conf
中,内容如下
server {
listen 8000;
server_name 127.0.0.1;
root /home/cookcyq/web/;
error_page 404 /40x.html;
error_page 500 502 503 504 /50x.html;
location / {
return 200 'Hello,world';
}
}
请务必记住好这几个配置,后面的案例都是以上面作为铺垫。
1.2 /home/cookcyq/web/
目录如下:
home
cookcyq
web
40x.html 内容为:40xxxxxxxx.html
50x.html 内容为:50xxxxxxxx.html
index.html 内容为: indexxxxxx.html
1.3 在 /etc/nginx/nginx.conf
配置文件中将上面的文件引入进来(下面这段下载时就自动加上的,如果没有看到手动加即可)
http{
...
include /etc/nginx/conf.d/*.conf;
}
1.4 重启 nginx ,访问 http://127.0.0.1/:8000/
即可看到输出 Hello,world
接下来正式进入本文
2、location -> return
2.1 返回状态码 + 字符串
location /a {
return 200 'Hi, I am a.';
}
重启 nginx,访问 http://127.0.0.1:8000/a
输出:
2.2 重定向
location /a {
return https://www.baidu.com;
}
重启 nginx,访问 http://127.0.0.1:8000/a
重定向到 https://www.baidu.com
3、location -> index
3.1 准备工作
在 /home/cookcyq/web/
目录下新建 a 目录,并创建 index.html 和 test.html,结构如下
home
cookcyq
web
a
index.html 内容为: Hello, index.html.
test.html 内容为:Hello,test.html.
3.2 使用
root /home/cookcyq/web/;
....
location /a {
index index.html;
}
现在访问 http://127.0.0.1:8000/a
时就会访问 /home/cookcyq/web/a/
下的 index.html
文件
index 的作用就是当没有访问任何文件时,则默认访问 index.html
现在我们来指定一个,如 http://127.0.0.1:8000/a/test.html
就会访问 /home/cookcyq/web/a/
下的 test.html
文件
如果我们指定一个不存在的文件比如 http://127.0.0.1:8000/a/ffff.html
则存在两种情况:
- 如果存在 , location / {} 则先访问
location / {
return "Hello,wolrd"
}
- 如果不存在 location / { … } ,则访问前面所配置好的 error_page 404 /40x.html; 即 /home/cookcyq/web/40.html。
4、location -> try_files
try_files 的细节蛮多的,稍不小心就掉进坑里,大家可要细心点哦。
4.1 准备工作
在 /home/cookcyq/web/
目录下新建 b 目录结构如下
home
cookcyq
web
b
foo.html 内容为: Hello, foo.html.
bar.html 内容为:Hello,bar.html.
index.html 内容为:Hello,b1, index.html.
b2
bird.html 内容为:Hello,Bird.html
index.html 内容为:Hello,b2, index.html
请务必记住好这些结构,下面将会使用以上结构作为示例。
4.2 使用
location /b {
try_files $uri $uri/ /b/index.html;
}
参数解释:
- 参数一 $uri 表示访问 /b/path/anyfile
- 参数二 $uri/ 表示访问 /b/path/ 时,访问该目录下的 index.xxx 索引文件
注意:如果该目录下不存在任何 index.xxx 索引文件则返回 403,如果访问不存在的目录则返回 500。 - 参数三 表示如果前面两个都找不到则访问 /b/index.html
注意:如果 /b/index.html 也不存在,则返回 500
接下来我会一一演示如何触发这三个参数:
4.2.1 访问 http://127.0.0.1:8000/b/foo.html
则对应 $uri
4.2.2 访问 http://127.0.0.1:8000/b/b2/bird.html
则对应 $uri
4.2.3 访问 http://127.0.0.1:8000/b/
则对应 $uri/
4.2.4 访问 http://127.0.0.1:8000/b/b2/
则对应 $uri/
4.2.5 访问 http://127.0.0.1:8000/b/oooo.html
由于 oooo.html 不存在,则对应第三个参数 /b/index.html。
4.2.6 访问 http://127.0.0.1:8000/b/b2/oooo.html
由于 oooo.html 不存在,则对应第三个参数 /b/index.html。
4.2.7 访问 http://127.0.0.1:8000/b/oooo.html
或 http://127.0.0.1:8000/b/b2/oooo.html
由于 oooo.html 不存在,且第三个参数 /b/index.html
也不存在的话(手动把index.html删掉或重命名即可实现效果),则返回 500
4.3 注意事项
- 第三个参数推荐使用绝对路径的形式
/path/index.html
,请不要采用$uri/index.html
,因为$uri/
是动态的目录,会随着 url 发生变化而变,这样很容易产生找不到目录而报 500 的问题 - 第三个参数的
/
代表 root 根目录,但它并不会累加 location /b {} ,比如第三个参数为/index.html
它对应的是root/index.html
而不是root/b/index.html
,这就是为什么上面的第三个参数为/b/index.html
,而如果是 location /b { index /index.html } 则会累加root/b/index.html
的形式,这点要注意。
5、location -> rewrite
rewrite 的细节也挺多的,不过理解起来很容易。
5.1 准备工作
在 /home/cookcyq/web/
目录下新建 c 目录结构如下
home
cookcyq
web
c
c.html 内容为:Hello, c.html.
r
1.html 内容为:Hello, 1.html.
2.html 内容为:Hello, 2.html.
3.html 内容为:Hello, 3.html.
请务必记住好这些结构,下面将会使用以上结构作为示例。
5.2 使用
语法:rewrite [匹配模式] [重定向目标] [指令(可选)]
5.2.1 简单使用
location /c {
rewrite ^(.*)$ /r/1.html;
}
当访问http://127.0.0.1:8000/c
http://127.0.0.1:8000/c/c.html
http://127.0.0.1:8000/c/xxx/xxx/xxx
都会重定向访问 root/r/1.html
记得把前面 location / { return 200 ‘Hello,world’ } 语句去掉,因为 return 指令会跳过下面的 location
5.2.2 带有 last 指令
location /c {
rewrite ^(.*)$ /r/1.html last;
# 不会触发这个,因为 last 会跳过下面的执行语句
rewrite ^(.*)$ /r/2.html last;
}
当访问http://127.0.0.1:8000/c
http://127.0.0.1:8000/c/c.html
http://127.0.0.1:8000/c/xxx/xxx/xxx
都会重定向访问 root/r/1.html
5.2.3 带有 last 指令
location /c {
rewrite ^(.*)$ /r/1.html last;
# 不会触发这个,因为 last 会跳过下面的执行语句,但它会继续走进下一个 location 块
rewrite ^(.*)$ /r/2.html last;
}
# 这里监听 /r/1.html 再做一次重定向
location = /r/1.html {
rewrite ^(.*)$ /r/3.html last;
}
当访问http://127.0.0.1:8000/c
http://127.0.0.1:8000/c/c.html
http://127.0.0.1:8000/c/xxx/xxx/xxx
都将重定向访问 root/r/3.html
5.2.4 带有 break 指令
location /c {
rewrite ^(.*)$ /r/1.html break;
# 不会触发这个,因为 break 会跳过下面的执行语句
rewrite ^(.*)$ /r/2.html last;
}
http://127.0.0.1:8000/c
http://127.0.0.1:8000/c/c.html
http://127.0.0.1:8000/c/xxx/xxx/xxx
都会重定向访问 root/r/1.html
5.2.5 带有 break 指令
location /c {
rewrite ^(.*)$ /r/1.html break;
# 不会触发这个,因为 break 会跳过下面的执行语句,同时也会跳过下面的 location 块
rewrite ^(.*)$ /r/2.html last;
}
# 由于 break 这里不会触发到
location = /r/1.html {
rewrite ^(.*)$ /r/3.html last;
}
http://127.0.0.1:8000/c
http://127.0.0.1:8000/c/c.html
http://127.0.0.1:8000/c/xxx/xxx/xxx
都会重定向访问 root/r/1.html
5.2.6 容易犯错的重定向案例
location /c {
rewrite ^(.*)$ /r/1.html last;
}
location = /r/1.html {
index /r/2.html;
}
思考一下,最终会重定向到哪里?
其实如果你知道 index 的作用,答案就简单多了,这里只会重定向到 root/r/1.html 而不会访问 root/r/2.html,因为 index 只是未访问任何文件时作为默认访问索引文件的指令。
5.3 注意事项
- rewrite 重定向目标如果不存在则走进 error_page 404 /40x.html
- 如果 root 是 /home/cookcyq/web 没有加
/
,那么重定向目标时得加/
,反之 root 有加/
则重定向目标可加可不加/
6、location -> root 与 alias
假如我们不想让每个 location 都继承 root,而是拥有自己的 root,那么 location 内的 root 与 alias 指令就是很好的选择。
6.1 准备工作
目录结构
home
cookcyq
web
d
1.html 内容为 Hello, 1.html
index.html 内容为 Hello, web index.html
my
d
foo.html 内容为 Hello, foo.html.
index.html 内容为 Hello, my index.html.
6.2 root
root /home/cookcyq/web/;
location /d {
root /home/cookcyq/my/;
try_files $uri $uri/ /d/index.html;
}
当我们访问 http://127.0.0.1:8000/d/foo.html
就会访问 /home/cookcyq/my/d/foo.html
6.3 alias
root /home/cookcyq/web/;
location /d {
alias /home/cookcyq/my/d/;
try_files $uri $uri/ /d/index.html;
}
当我们访问 http://127.0.0.1:8000/d/foo.html
就会访问 /home/cookcyq/my/d/foo.html
6.4 root 与 alias 的区别
root 指令最终形成的路径为:root+location xxx/*
alias 指令最终形成的路径为:alias/*