jquery - 忽略 Access-Control-Expose-Headers 设置

标签 jquery ajax apache http-headers

在我的 Apache Web 服务器配置中,我添加了对不属于标准六个 header 的两个 header 的支持:

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Expose-Headers: Content-Disposition,X-Filename

我的文件导出 CGI 脚本打印包含这两个字段数据的 header ,例如:

...
print "Content-Disposition: attachment; filename=%s\n" % (out_fn)
print "X-Filename: %s\n" % (out_fn)
...

我的客户端 AJAX 调用尝试在成功的 AJAX 请求上检索 Content-Disposition 的值:

var export_form = new FormData();
export_form.append("settings", JSON.stringify(settings));
export_form.append("format", format);
$.ajax({
    url: "services/export_data.py",
    type: "POST",
    async: true,
    cache: false,
    data: export_form,
    processData: false,
    contentType: false,
    success: function(response, textStatus, jqXHR) {
        console.log("success");
        console.log(jqXHR.getAllResponseHeaders());
        console.log(jqXHR.getResponseHeader('Content-Disposition'));
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.log("export_form submit failed:", jqXHR.status, jqXHR.statusText);
        console.log(jqXHR);
    }
});

我在客户端的测试请求完成并运行 success 回调,我在 response 字段中获取文件数据,但我得到 null 响应 header Content-Disposition

换句话说,console.log(jqXHR.getAllResponseHeaders()) 的示例结果为:

Date: Sat, 04 Mar 2017 19:42:27 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_python/3.5.0- Python/2.7.5 mod_perl/2.0.10 Perl/v5.16.3
Transfer-Encoding: chunked
Content-Type: application/pdf
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Disposition,X-Filename
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100

console.log(jqXHR.getResponseHeader('Content-Disposition')) 的结果为空时:

null

为什么我的 AJAX 请求无法检索 Content-Disposition 的值,而我已通过 Web 服务器配置显式地使其可用,并且已在响应中正确设置它?

<小时/>

为了解决换行符问题,我使用 sys.stdout.write 来更好地控制输出,例如:

sys.stdout.write("Content-Type: %s\n" % (mime_type))
sys.stdout.write("Content-Disposition: attachment; filename=%s\n" % (output_fn))
sys.stdout.write("X-Filename: %s\n" % (output_fn))
sys.stdout.write("Content-Description: File to download\n\n")
with open(out_fn, "rb") as out_fh:
    sys.stdout.write(out_fh.read())

不幸的是,通过 console.log(jqXHR.getResponseHeader('Content-Disposition'))console.log(jqXHR.getResponseHeader) AJAX 响应仍然看不到这两个 header ('X-Filename')),均为 null

最佳答案

Access-Control-Expose-Headers 仅适用于 CORS 请求:您的情况下的 Content-DispositionX-Filename 添加到允许其他域查看是否从您的服务器请求数据的六个标准 header 。

不过,您发送的请求看起来不像是跨源的:URL services/export_data.py 并不指向另一个域以及 console 的输出.log(jqXHR.getAllResponseHeaders()) 包含诸如 ServerDate 之类的 header ,这些 header 不在六个标准 header 和两个公开 header 中。

<小时/>

我认为你的问题是服务器端的,而不是Javascript,而且你实际上并没有发送你想要包含的两个 header 。

CGI 脚本似乎是用 Python 编写的(基于 URL 中的文件扩展名)。如果是这种情况,print "\n" 实际上会打印两个换行符,并且由于空行在 HTTP 中分隔 header 和数据,因此您添加的两个 header 将包含在 HTTP 响应中,但会被处理作为数据而不是标题。在添加 Content-Disposition 之前是否有任何 print 语句?这可以解释为什么它也没有显示为标题。

要解决此问题,只需删除脚本中的尾随 \n 即可:

...
print "Content-Disposition: attachment; filename=%s" % (out_fn)
print "X-Filename: %s" % (out_fn)
...

关于jquery - 忽略 Access-Control-Expose-Headers 设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42600632/

相关文章:

javascript - 检测 <embed> 标签无法加载视频

apache - 主机名在另一个 Tomcat 服务器上不工作

linux - 为什么我在浏览器中出现禁止错误

php - 同一台服务器上的 Laravel 4.2 环境

javascript - 如何在饼图中创建超链接

javascript - 使用 Chrome 扩展访问/操作实际 DOM

javascript - 根据选择显示或隐藏 div

javascript - 动态页面和类似 Facebook 的框的解决方法

javascript - spring mvc json响应ajax

javascript - Ajax 调用未获得成功响应