我用Nginx搭前端项目一直访问不到的原因
我在第一次接触到Nginx的时候,总是会把nginx.conf的配置文件的这个 root 的这个配置写成 /usr/docker-nginx/html/dist
在不断的试错的过程中,我知道了自己到底错在哪了,所以我把我的理解画成了这张图。(文章最后有我配置Nginx的步骤)
为什么我的前端项目部署Nginx成功后,用浏览器进行访问,但是却一直拿不到数据?
前段时间我跟着做了一个尚硅谷的尚品汇的项目,我试着把项目用Nginx进行上线,可是项目成功部署上去了,但是有些要请求服务器的
数据却一直请求不到,这个时候我才发现问题,因为我之前有个多人开发的项目是可以拿得到的,Nginx也没有多进行其他的配置
所以我以为直接把项目部署上去就可以拿到数据了,结果自己在尝试上线尚品汇这个项目的时候就出错了。
-
先看一个我们多人开发的项目的前端那个接口地址是怎么写的
在封装axios的时候,因为当项目打包了之后,前端的一个devServer就没有用了,我们当时这个项目为了方便
直接把baseURL换成了全地址的,这里打马赛克的就是我们的后端服务器的ip地址
然后我们的Nginx的nginx.conf配置就变成了
ini
listen 80;
server_name Nginx所在服务器的ip地址;
location / {
root /usr/share/nginx/html/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
-
到了我们的尚品汇这个项目的时候
当时我还是不知道Vue项目打包后那个devServer是不可以用的
所以就一直保持这个baseURL: "/api" 这个配置,到最后打包也没有进行更改
然后我就直接把尚品汇这个项目打包后的dist文件夹直接放到了Nginx挂载的html文件夹那了
ini
listen 80;
server_name Nginx所在服务器的ip地址;
location / {
root /usr/share/nginx/html/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
当我成功部署到线上之后,进行访问的时候。发现数据响应不回来
这个时候我百思不得其解,后来找了很久的博客啊什么的,我才发现,打包后的devServer是不生效的,是需要Nginx去进行配置的
于是我去修改了nginx.conf
bash
server
{
listen 80;
server_name Nginx所在服务器的ip地址;
location / {
root /usr/share/nginx/html/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://gmall-h5-api.atguigu.cn;
}
}
再次访问,ok成功了
总结来说就是,如果前端项目打包后的baseURL改为全路径之后,Nginx这里就不需要再进行配置代理了
如果前端项目打包后的baseURL还是/api这样的非全路径的话,Nginx就需要进行配置代理,相当于devServer
Access-Control-Allow-Origin 的问题
- 首先为什么会需要 Access-Control-Allow-Origin ,这个是什么东西?
我以前以为这个响应头是为了解决跨域问题的,现在思考了以后,发现跨域和这个响应头是两码事
在前端调试接口的这个阶段,需要使用devServer来进行一个代理,去访问后端的接口,这个时候我一直想不明白这个响应头有什么用
现在想想,devServer是为了解决跨域问题的,同源策略只会存在于浏览器和服务器之间的交互过程中,服务器和服务器之间不涉及同源
所以 Access-Control-Allow-Origin ,解决了什么?它实际上是在给浏览器做提示,表示该请求源是否能够获得服务器返回的数据
而不是解决跨域问题,当Access-Control-Allow-Origin的值为 * 时,也就意味着不管是哪个ip请求,都可以响应数据
- 这显然是非常不安全的,那我们应该怎么处理?看下面这两段代码
在项目还在测试阶段的时候,我们为了方便,在后端的接口上面都加了这段代码
java
response.setHeader("Access-Control-Allow-Origin","*");
但是要注意有个问题啊,就是不管是谁来访问,我们都响应这个请求头,因为我们的值给的是 *
这样是不安全的,意味着谁来都可以请求数据了,那我们应该怎么处理?
java
response.setHeader("Access-Control-Allow-Origin","前端项目上线的ip地址或者域名");
因为我们的数据只需要给我们的前端的项目进行访问,所以我们可以直接限制只有谁来能够拿得到数据
所以我们可以直接把值设置为前端项目上线的ip或者域名,这样如果其他源想要拿到我们后端的数据的时候,浏览器就会进行比对
比对这个"Access-Control-Allow-Origin"的值,和你这个源头的地址是否相同,如果不同就会把结果进行拦截,不让你拿到这个数据
下面是我试错了好多次总结下来的部署经验了
1.拉取Nginx镜像
docker pull nginx:1.18.0
2.创建挂载目录
bash
mkdir -p /usr/docker-nginx/{conf,html,logs}
3.获取配置文件
bash
# 生成容器
docker run --name nginx -p 80:80 -d nginx
# 将容器nginx.conf文件复制到宿主机
docker cp nginx:/etc/nginx/nginx.conf /usr/docker-nginx/conf/nginx.conf
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /usr/docker-nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /usr/docker-nginx/
#之后进行容器的删除
# 直接执行docker rm nginx或者以容器id方式关闭容器
# 找到nginx对应的容器id
docker ps
# 关闭该容器
docker stop nginx
# 删除正在运行的nginx容器
docker rm -f nginx
4.修改并配置成自己的配置文件
在nginx.conf中添加如下内容:
ini
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name Nginx所在服务器的地址可以直接写成localhost;
charset utf-8;
location / {
root /usr/share/nginx/html/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
5.配置静态资源
将静态资源(如前端打包的dist文件夹)放到 /usr/docker-nginx/html 下面就可以直接访问了
6.启动nginx
bash
docker run -d \
-p 80:80 \
--name nginx \
--restart=always \
-e TZ="Asia/Shanghai" \
-v /usr/docker-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/docker-nginx/conf/conf.d:/etc/nginx/conf.d \
-v /usr/docker-nginx/logs:/var/log/nginx \
-v /usr/docker-nginx/html:/usr/share/nginx/html \
nginx:1.18.0
7.直接去浏览器输入你Nginx部署的服务器地址
如果不输入端口号,默认就是走的80端口,就可以看到你部署的东西了