目录
一、问题描述:
在前后端分离开发中,要实现头像上传功能。选择使用element ui组件库中的upload组件实现,组件中action中地址为后端接口地址“/api/upImage”。在前端使用地址重写试下跨域,如下图。但在后端读取session时,为null(session在登录时已经设置)。
二、问题分析:
首先分析下头像上传的流程,用户上传头像文件后,浏览器会访问upload组件中指向的接口:http://localhosst:8080/api/upImage
而后端提供的接口地址为:http://localhosst:8081/cinema/upImage ;这两个地址之间的转换就是通过图1中proxy代理实现的。而这个代理就是导致session丢失的关键。
在后端,真正的session路径在/cinema下,但是请求http://localhosst:8080/api/upImage携带的cookie在/api路径,在/api路径找/cinema下cookie自然找不到,就导致虽然能访问到接口但session为空。
三、问题解决
1.方法1(开发环境):
解决思路就是令前端访问路径与后端路径匹配,也就是地址中端口后的第一个路径是相同的(/api或/cinema)。可以通过修改前端或者修改后端实现
- 修改前端:
将前端中的/api修改成后端的入口路径/cinema(如下图),这样浏览器访问路径为http://localhosst:8080/cinema/upImage,cookie携带在/cinema下,后端可以读取。
注意在修改时将axois中的baseurl同步改成/cinema,以免影响其他功能
- 修改后端:
同样,可以将后端的context-path修改成“/api”(如下图),这样达到的效果与修改前端相同。
2.方法2(生产环境):
在生产环境中,如果使用nginx反向代理,可以在nginx.conf中修改而不需要修改源代码。在nginx中也可以配置cookie转换(即proxy_cookie_path):
location /api {
proxy_pass http://123.249.19.**:8081;
proxy_cookie_path /cinema /api;
rewrite /api/(.*) /cinema/$1 break;
}
通过这个“proxy_cookie_path /cinema /api;”指令告诉nginx,在代理到"/cinema"的请求中,要将 cookie 的路径从"/cinema"调整为"/api"。
3.方法3(生产环境):
如果部署时没有使用nginx反向代理,将前端代码构建后放入后端webapp或resource文件夹中,不会丢失session (前提得将action中的地址改成后端对应的接口地址(/cinema/upImage),因为构建后代理失效)
夹带私货:
问题:nginx的配置文件中不能直接在代理地址后加/cinema
(1)配置 proxy_pass 时,当在后面的 url 加上了 /,相当于是绝对路径,则 Nginx 不会把 location 中匹配的路径部分加入代理 uri。
location /api {
proxy_pass http://123.249.19.**:8081;
#访问地址:http:127.0.0.1:8080/api/upImage
#转换地址:http:123.249.19.**:8081/api/upImage
}
(2)如果配置 proxy_pass 时,后面没有 /,Nginx 则会把匹配的路径部分加入代理 uri。
location /api {
proxy_pass http://123.249.19.**:8081/cinema;
#访问地址:http:127.0.0.1:8080/api/upImage
#转换地址:http:123.249.19.**:8081/cinema/upImage
}
upload中上传文件跨域问题,需要在后端crossorigin()须在括号中显式指明地址