在我的 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-Disposition
和 X-Filename
添加到允许其他域查看是否从您的服务器请求数据的六个标准 header 。
不过,您发送的请求看起来不像是跨源的:URL services/export_data.py
并不指向另一个域以及 console 的输出.log(jqXHR.getAllResponseHeaders())
包含诸如 Server
或 Date
之类的 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/