在我的Apache Web服务器configuration中,我添加了两个不属于标准6的头的支持:
Header set Access-Control-Allow-Origin "*" Header set Access-Control-Expose-Headers: Content-Disposition,X-Filename
我的文件导出CGI脚本打印包含这两个字段的数据的标题,例如:
... 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); } });
我在客户端的testing请求完成并运行success
callback,我得到的文件数据返回到response
字段,但我得到null
的响应头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服务器configuration使其明确可用时,我已经在响应中正确设置了该值?
为了解决换行问题,我使用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('Content-Disposition'))
和console.log(jqXHR.getResponseHeader('X-Filename'))
的AJAX响应仍然不可见,它们都是null
。
Access-Control-Expose-Headers
只适用于CORS请求:在你的情况下, Content-Disposition
和X-Filename
被添加到六个标准的头部,而另一个域允许看到它是否从服务器请求数据。
但是,您要发送的请求看起来不是跨源的:URL services/export_data.py
不指向另一个域,而console.log(jqXHR.getAllResponseHeaders())
的输出包含标头,如server
或Date
不在六个标准和两个暴露标题。
我认为你的问题是服务器端,而不是与JavaScript,而你实际上并没有发送你想包括的两个头。
CGI脚本似乎是用Python编写的(基于URL中的文件扩展名)。 如果是这种情况, print "\n"
实际上打印两个换行符,并且由于空行在HTTP中分隔标题和数据,所添加的两个标题将包含在HTTP响应中,但被视为数据而不是标题。 在添加Content-Disposition
之前是否有任何print
语句? 这将解释为什么这也没有显示为头。
要解决这个问题,只需删除脚本中的尾部\n
:
... print "Content-Disposition: attachment; filename=%s" % (out_fn) print "X-Filename: %s" % (out_fn) ...