从session可得普通请求头token信息,不能获取上传文件时的token信息【已解决,用于记录】

发布于 2022-09-12 01:47:04 字数 4135 浏览 16 评论 0

问题描述

前后端分离项目,文件上传,后端过滤器中设置了跨域,前端axios设置了请求拦截器和允许携带cookie。
访问一个普通接口时,过滤器可以从请求头中获取token,并且可以从session中获取此token对应的信息:
request.getSession().getAttribute(token);//非空
而是用<el-upload>上传文件时,token有数据,但是request.getSession().getAttribute(token);//为空

后端过滤器主要代码,没有问题,可不看:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

String origin = request.getHeader("Origin");
// 响应标头指定 指定可以访问资源的URL路径
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "1800");
//  设置  受支持请求标头(自定义  可以访问的请求头  例如:Token)
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,token,Origin,Content-Type,Accept");
// 指示的请求的响应是否可以暴露于该页面。当true值返回时它可以被暴露
response.setHeader("Access-Control-Allow-Credentials", "true");


/**
 * 发送两次请求
 * 第一次是 request.getMethod()=OPTIONS
 * 第二次 request.getMethod()=GET/POST,
 * 如果是OPTIONS,让其响应成功
 */
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
    response.setStatus(HttpServletResponse.SC_OK);
    return;
}
//如果是一个被允许的URI(例如登录),让其通行
if (allowURI(request.getRequestURI())) {
    chain.doFilter(request, response);
    return;
}
//获取请求头中的token
String token = request.getHeader("Authorization");
if (StringUtils.isEmpty(token)) {
    return;
}
Object attribute = request.getSession().getAttribute(token);
if (attribute == null) {
    return;
}
chain.doFilter(request, response);
}

前端配置,没有问题,可不看:

//请求拦截器,作用就实在每次请求的请求头中加入 Authorization:token字符串
axios.interceptors.request.use(config => {
  config.headers.Authorization = window.sessionStorage.getItem('token');
  return config
});


axios.defaults.withCredentials = true; //允许携带cookie

文件上传使用的是<el-upload>,它使用的不是axios,所以要在其请求中继续加入请求头Authorization

<el-upload :action="uploadURL" //文件上传路径 
           :onError="uploadError" //出现错误时调用的方法 uploadError(err, file, fileList)
           :on-preview="handlePreview" //点击图片触发 handlePreview(file)
           :on-remove="handleRemove" //被移除时触发的函数handleRemove(file, fileList)
           list-type="picture-card" //文件如何展示,查看官方文档
           :headers="requestHeader" //请求头,就是要加上Authorization
           :on-success="handleSuccess" //上传成功回调的函数
           :file-list="fileList" //当前已经上传的文件列表
           class="upload-file"
           style="margin-bottom: 2%;margin-left: 10%">
  <i class="el-icon-plus"></i>
</el-upload>

<el-upload>标签绑定了请求头

data() {
    return {
        
        requestHeader: {  //未上传图片的请求头加token
          Authorization: window.sessionStorage.getItem("token")
        },
    }
}

做了如上操作之后,普通接口可以正常访问,但是文件上传的接口不能正常访问。
image.png

问题原因:

axios加了Authorizationaxios.defaults.withCredentials = true;
而给<el-upload>只加请求头Authorization
还要给<el-upload>:with-credentials="true"属性,就可以解决问题了

<el-upload :action="uploadURL"
           :onError="uploadError"
            :with-credentials="true" //就是这个
           :on-preview="handlePreview"
           :on-remove="handleRemove"
           list-type="picture-card"
           :headers="requestHeader"
           :on-success="handleSuccess"
           :file-list="fileList"
           class="upload-file"
           style="margin-bottom: 2%;margin-left: 10%">
  <i class="el-icon-plus"></i>
</el-upload>

image.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森罗 2022-09-19 01:47:04

已解决

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文