前后端分离的情况下,的ajax方法获取不到跨域的响应头?

问题描述

我目前在做一个框架,就是前后端分离,需要把一些数据放到响应头中,但是,前端获取不到响应头的其他信息,只能获取到。通过xhr.getAllResponseHeaders()只能获取这个值:content-type: application/json;charset=UTF-8

问题出现的环境背景及自己尝试过哪些方法

通过查找csdn网站,博客园等,都没有找到相应的解决方案。

相关代码

 //获取请求头信息
    getHeaders: function () {
        $.ajax({
            'type': 'head',
            'url': constant.server_path + "/index",
            'success': function (data, status, xhr) {
                var header = {
                    //登录用户名
                    "name": xhr.getResponseHeader('name'),
                    // 登录session
                    "session": xhr.getResponseHeader('session'),
                    // 用户编号
                    "userId": xhr.getResponseHeader('userId'),
                };
                console.log("name:" + header.name + ",session:" + header.session + ",userId:" + header.userId);
                console.log(xhr.getAllResponseHeaders())
            },
            'error': function (data, status, xhr) {

            }
        })
    },

后端服务器相应结果如图所示:

clipboard.png

你期待的结果是什么?实际看到的错误信息又是什么?

响应是有值的,但是获取不到这个值。我希望能拿到响应头信息的值。

阅读 3.5k
2 个回答

1,不要用$.ajax了,自己在原生xhr上封装下,很简单的
2,$.ajax已经这么多年了,还没有任何改变了,还在吃老本,已经不适合当下的前后端分离中的xhr请求了,因为除了200,之外的http状态码操作都做不了,太鸡肋了,http状态可不止200一个,还有其他很多的
3,所以有这个时间,你完全可以封装一下xhr来用,然后根据你们的业务慢慢来升级它

我的这个问题已经解决了。

在使用跨域的方式进行前后端的交互时,浏览器只会使用默认的header,如图所示:

图片描述

因为,我们需要在服务端开放权限,允许客户端使用服务端自定义的header值,即使用该字段Access-Control-Expose-Headers控制权限,如代码所示:

      /**
     * 在业务处理器处理请求之前被调用 如果返回false
     * 从当前的拦截器往回执行所有拦截器的afterCompletion(),
     * 再退出拦截器链, 如果返回true 执行下一个拦截器,
     * 直到所有的拦截器都执行完毕 再执行被拦截的Controller
     * 然后进入拦截器链,
     * 从最后一个拦截器往回执行所有的postHandle()
     * 接着再从最后一个拦截器往回执行所有的afterCompletion()
     *
     * @param request
     * @param response
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
//        允许跨域
        response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_ORIGIN.key(), request.getHeader(HEADER_ACCESS_CONTROL_ALLOW_ORIGIN.value()));
        response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_METHODS.key(), HEADER_ACCESS_CONTROL_ALLOW_METHODS.value());
        response.setHeader(HEADER_ACCESS_CONTROL_MAX_AGE.key(), HEADER_ACCESS_CONTROL_MAX_AGE.value());
        response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_HEADERS.key(), HEADER_ACCESS_CONTROL_ALLOW_HEADERS.value());
//        允许session
        response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS.key(), HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS.value());
//      允许客户端在header中使用哪些数值
        response.setHeader(ACCESS_CONTROL_EXPOSE_HEADERS.key(), ACCESS_CONTROL_EXPOSE_HEADERS.value());
        return true;
    }

枚举类

public enum HeaderEnum {

    //    解决跨域的问题
    HEADER_ACCESS_CONTROL_ALLOW_ORIGIN("Access-Control-Allow-Origin", "Origin"),
    HEADER_ACCESS_CONTROL_ALLOW_METHODS("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH"),
    HEADER_ACCESS_CONTROL_MAX_AGE("Access-Control-Max-Age", "3600"),
    HEADER_ACCESS_CONTROL_ALLOW_HEADERS("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"),
    //        解决session的问题
    HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS("Access-Control-Allow-Credentials", "true"),
    ACCESS_CONTROL_EXPOSE_HEADERS("Access-Control-Expose-Headers", "name,session,userId");

    HeaderEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 响应key值
     */
    private String key;

    /**
     * 响应value值
     */
    private String value;

    public String key() {
        return key;
    }

    public String value() {
        return value;
    }

}

这样客户端通过 xhr.getResponseHeaders(key) 获取响应的key值

 $.ajax({
            'type': 'head',
            'url': constant.server_path + "/index",
            'success': function (data, status, xhr) {
                var header = {
                    //登录用户名
                    "name": xhr.getResponseHeader('name'),
                    // 登录session
                    "session": xhr.getResponseHeader('session'),
                    // 用户编号
                    "userId": xhr.getResponseHeader('userId'),
                };
                console.log("name:" + header.name + ",session:" + header.session + ",userId:" + header.userId);
                console.log(xhr.getAllResponseHeaders())
            },
            'error': function (data, status, xhr) {

            }
        })
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏