说我有一个HTML页面,该页面可以通过http://example.com/redir.php?id=someID
访问。
我希望一些JavaScript在执行时触发http://example.com/?file=hgc56gjyd
的下载,并以newFileName
的名称提供。
这是我的尝试:
var c = document.createElement("a");
c.href = "?file=hgc56gjyd";
c.download = "newFileName";
c.click();
但是当我执行此操作时,实际的请求是向http://example.com/redir.php?file=hgc56gjyd
发送的。请注意添加的'redir.php'
。该URL错误,下载的文件为空。但是在这种情况下,更改名称即可。
如果我写出整个URL或使用“ /”或“ ./”(开头):
c.href = "http://example.com/?file=hgc56gjyd"
c.href = "/?file=hgc56gjyd"
c.href = "./?file=hgc56gjyd"
然后download
属性不会生效,因此生成的文件不会重命名为newFileName
。
在获得download
的功能的同时,如何触发对正确URI的请求?
这是在Chrome中。
答案 0 :(得分:1)
这样做:
c.href = "?file=hgc56gjyd";
在http://example.com/redir.php?id=someID
的文档中,您实际上是在这样做:
c.href = "http://example.com/redir.php?file=hgc56gjyd";
// Note ---------------------^^^^^^^^^
如果您希望将其设置为http://example.com/?file=hgc56gjyd
,则不必使用绝对路径-网站内的绝对路径 是Bad Thing™:-)-只需使用前导/
或前导./
:
c.href = "/?file=hgc56gjyd";
// -------^
或
c.href = "./?file=hgc56gjyd";
// -------^^
如果要转到域根目录,则不管链接所在页面的URL是什么,请使用前者(/
);如果您只想要链接所在页面级别的默认URL,则使用后者(./
)。在您的示例中,这些是同一回事,但是如果它们位于http://example.com/somethinghere/redir.php?id=someID
的页面上,则不会是这样。
实时示例(使用https://stacksnippets.net
代替http://example.com
的{{1}}和js
):
redir.php
console.log("Location: " + location);
// Your current code
var c = document.createElement("a");
c.href = "?file=hgc56gjyd";
c.download = "newFileName";
// Notice the `js` on this (which is like your redir.php)
console.log("Your Link:" + c.href);
// The corrected code (#1
var c2 = document.createElement("a");
c2.href = "/?file=hgc56gjyd";
c2.download = "newFileName";
// Notice there's no `js` now
console.log("Fix1: " + c2.href);
// The corrected code (#2
var c3 = document.createElement("a");
c3.href = "./?file=hgc56gjyd";
c3.download = "newFileName";
// Notice there's no `js` now
console.log("Fix2: " + c3.href);
在问题和评论中,您已经说过使用.as-console-wrapper {
max-height: 100% !important;
}
“有效”来重命名文件(但不下载它,而是得到一个空文件),但是使用了正确的路径(绝对路径或以上任一解决方案)“无效”,因为它使用了服务器中的名称。但是区别不在于路径本身,而是服务器根据路径发送的内容:"?file=hgc56gjyd"
标头的文件名将胜过放置在Content-Disposition
属性中的所有内容。实际的下载脚本(位于download
)发送它。显然/
脚本没有。
解决方案是将文件名方面转移到服务器,并确保返回带有以下标头的文档:
redir.php
例如,如果下载是通过PHP代码处理的,则可以这样做:
Content-Disposition: attachment; filename=newFileName
这样,服务器会告诉浏览器名称。仍然允许浏览器忽略它(但以我的经验,通常使用它)。
如果所有操作均失败(例如,因为您无法更改发送该响应的服务器代码),则还有一个选择:使用Blob和URL.createObjectURL
(这是{{3 }})。这是使用surprisingly well supported的示例:
<!-- language: lang-php -->
<?php
header("Content-Disposition: attachment; filename=newFileName")
成功使用了// In an event handler...
fetch("./?file=hgc56gjyd")
.then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.blob();
})
.then(blob => {
var c = document.createElement("a");
c.href = URL.createObjectURL(blob);
c.download = "bar.json";
c.click();
})
.catch(e => {
alert(e.message);
});
名称。
如果您不能那样,恐怕您真的很倒霉。 :-|