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

在我的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请求完成并运行successcallback,我得到的文件数据返回到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-DispositionX-Filename被添加到六个标准的头部,而另一个域允许看到它是否从服务器请求数据。

但是,您要发送的请求看起来不是跨源的:URL services/export_data.py不指向另一个域,而console.log(jqXHR.getAllResponseHeaders())的输出包含标头,如serverDate不在六个标准和两个暴露标题。


我认为你的问题是服务器端,而不是与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) ...