Content-Disposition附件在XMLHttpRequest中是否被阻止?

10

我想从我编写的C# web服务器上执行一个javascript xhr请求,以获取一个png文件。这是我使用的代码:

    var imgUrl = "http://localhost:8085/AnImage.png?" + now;
    var request = new XMLHttpRequest();
    request.open('GET', imgUrl, false);
    request.send(); // this is in a try/catch

在服务器端,我发送文件并添加Content-Disposition头。我获得了以下响应。 The headers obtained in the response, with Firebug 我确保Content-Disposition在Content-Type之后附加在头部(屏幕截图来自Firebug,它按字母顺序附加)。
结果是没有触发对话框,我在响应中漏掉了什么吗?
编辑: 出于几个原因,我想在JavaScript中执行所有操作。 首先:我不想显示图片,我希望将一切都藏在幕后。 其次,在请求图像时,我希望仅对特定请求添加Content-Disposition。这些请求使用值为“AttachmentRequest”的“Warning”标头标记。
request.setRequestHeader("Warning","AttachmentRequest");

为什么你需要这样做?你可以使用Image对象加载图像,不需要使用Ajax。 - mpm
@camus 完全不同。像这样使用 content-disposition 应该会“强制”用户下载文件,而不仅仅是让浏览器为其“下载”。 - Ian
@Ian 使用ajax也不会强制任何事情。 - mpm
1
@camus 这就是问题的关键。如何强制下载。但无论如何,除非有某种表单POST需要生成图像或其他内容(这里看起来不是这样),否则不需要使用AJAX。 - Ian
我的观点仍然成立,你不能使用ajax来做那件事。 - mpm
@mpm 你怎么能推断出这里没有动态图像生成? - FlavorScape
1个回答

11

我认为当通过XHR请求时,Content-Disposition不会触发任何文件保存对话框。使用XHR意味着您将在代码中处理结果。

如果你想让用户被提示保存图像到文件中,我已经成功地使用了这个技巧:

window.open("http://localhost:8085/AnImage.png?" + now);

这种方法的缺点是它会在头部到达之前短暂地闪现一个空白的窗口,然后新窗口关闭并出现“保存文件”对话框。

使用 iframe 可以避免窗口闪烁:

var f = document.createElement('iframe');
f.style.position = "absolute";
f.style.left = "-10000px";
f.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(f);

另外,我想知道Content-Dispositionimg元素的处理是否有任何影响:

var img = document.createElement('img');
img.style.position = "absolute";
img.style.left = "-10000px";
img.src = "http://localhost:8085/AnImage.png?" + now;
document.body.appendChild(img);

我没有尝试过那样做,但浏览器可能会遵循这个标头。你需要确保在你想支持的所有浏览器上进行测试。


1
我认为通常不使用window.open/闪烁的方法是通过使用iframe...但仍然使用content-disposition - Ian
appendChild的解决方法不起作用,但window.open的技巧在我们想要使用的浏览器(FF,Chrome和cough cough IE)上运行得很好。非常感谢TJ。 - malber
@Ian:说得好,是的(尴尬地说,那通常是我做的事情,虽然在我的情况下几乎总是涉及POST,所以更加复杂)。谢谢,我已经更新了答案。 - T.J. Crowder
@malber:很高兴能帮到你!你也可以尝试使用iframe(我已经更新了答案,在上面的评论中,我链接了我的另一个回答,描述了一种显示“稍等片刻”div或类似内容直到下载开始的技术...)。 - T.J. Crowder
TJ的iframe技巧完美地运行了,谢谢!请问你能否将第一个代码片段中的document.body.appendChild(img);替换为document.body.appendChild(f);吗? - malber
能否从头文件中获取Content-Disposition?我也遇到了同样的问题。当我尝试从header读取时,它返回null。 - Arun M R Nair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接