Javascript 如何从内容处置中获取文件名
作为对ajax的响应,我下载了这个文件。如何从内容配置中获取文件名和文件类型,并为其显示缩略图。我得到了很多搜索结果,但找不到正确的方法Javascript 如何从内容处置中获取文件名,javascript,ajax,filenames,file-type,content-disposition,Javascript,Ajax,Filenames,File Type,Content Disposition,作为对ajax的响应,我下载了这个文件。如何从内容配置中获取文件名和文件类型,并为其显示缩略图。我得到了很多搜索结果,但找不到正确的方法 $(".download_btn").click(function () { var uiid = $(this).data("id2"); $.ajax({ url: "http://localhost:8080/prj/" + data + "/" + uiid + "/getfile", type: "G
$(".download_btn").click(function () {
var uiid = $(this).data("id2");
$.ajax({
url: "http://localhost:8080/prj/" + data + "/" + uiid + "/getfile",
type: "GET",
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
},
success: function (response, status, xhr)
{
var header = xhr.getResponseHeader('Content-Disposition');
console.log(header);
}
});
控制台输出:
inline;filename=demo3.png
这是我以前如何使用它的。
我假设您将附件作为服务器响应提供
我从REST服务response.setHeader(“Content-Disposition”,“attachment;filename=XYZ.csv”)代码>
编辑:
编辑答案以适应您的问题-使用内联
而不是附件
function(response, status, xhr){
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('inline') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
}
}
尝试以下解决方案:
var contentDisposition = xhr.getResponseHeader('Content-Disposition');
var startIndex = contentDisposition.indexOf("filename=") + 10; // Adjust '+ 10' if filename is not the right one.
var endIndex = contentDisposition.length - 1; //Check if '- 1' is necessary
var filename = contentDisposition.substring(startIndex, endIndex);
console.log("filename: " + filename)
有一个npm包可以完成这项工作:或者只是:
var fileName = xhr.getResponseHeader('Content-Disposition').split("filename=")[1];
这是对marjon4答案的改进
选择答案的一个非常简单的方法是像这样使用split
var fileName = xhr.getResponseHeader('content-disposition').split('filename=')[1].split(';')[0];
注意:如果文件名本身包含分号(;),此解决方案可能无法按预期工作。在本例中,标题如下所示:
attachment; filename="test-file3.txt"
因此,我能够使用命名组regexp非常轻松地提取文件名:
const regExpFilename = /filename="(?<filename>.*)"/;
const filename: string | null = regExpFilename.exec(contentDispositionHeader)?.groups?.filename ?? null;
const regExpFilename=/filename=“(?*”)/;
常量文件名:string | null=regExpFilename.exec(contentDispositionHeader)?.groups?.filename??无效的
我知道我在这里有点离题,因为OP在文件名周围没有引号,但仍在共享,以防有人遇到与我刚才相同的模式如果您不使用多部分正文,则可以使用此函数。它从内容处置头值(类似于:inline;filename=demo3.png的字符串)中提取文件名,并根据需要进行解码
const getFileNameFromContentDisposition = disposition => {
if (disposition
&& (disposition.startsWith('attachment') || disposition.startsWith('inline'))
) {
let filename = disposition.startsWith('attachment')
? disposition.replace("attachment;", "")
: disposition.replace("inline;", ""); //replaces first match only
filename = filename.trim();
if (filename.startsWith("filename=")) {
filename = filename.replace("filename=", "")
.slice(1, filename.length - 1); //remove quotes
} else if (filename.startsWith("filename*=")) {
filename = filename.replace("filename*=", "")
.split("''").slice(1).join("''"); //remove encoding and ''
filename = decodeURIComponent(filename);
}
return filename;
}
}
函数的结果可分为名称和扩展名,如下所示:
let name = getFileNameFromContentDisposition("inline; filename=demo.3.png").split(".");
let extension = name[name.length - 1];
name = name.slice(0, name.length - 1).join(".");
console.log(name); // demo.3
console.log(extension); //png
例如,可以使用svg显示缩略图:
let colors = {"png": "red", "jpg": "orange"};
//this is a simple example, you can make something more beautiful
let createSVGThumbnail = extension => `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20">
<rect x="0" y="0" width="18" height="20" fill = "#FAFEFF"/>
<rect x="0" y="7" width="18" height="6" stroke="${colors[extension] || "blue"}" fill = "${colors[extension] || "blue"}"/>
<text stroke = "white" fill = "white" font-size = "6" x = "0" y = "12.5" textLength = "18">${extension.toUpperCase()}</text>
</svg>`;
...
//You can use it as HTML element background-image
let background = "data:image/svg+xml;base64," + btoa(new TextDecoder().decode(createSVGThumbnail("png")));
let colors={“png”:“red”,“jpg”:“orange”};
//这是一个简单的例子,你可以做一些更漂亮的东西
让createSVGThumbnail=扩展=>`
${extension.toUpperCase()}
`;
...
//您可以将其用作HTML元素背景图像
让background=“data:image/svg+xml;base64”+btoa(新的textdecker().decode(createSVGThumbnail(“png”));
如果您想获取文件名并同时支持怪异的url编码UTF-8和ascii头,您可以使用如下内容
公共getFileName(处置:string):string{
常量utf8FilenameRegex=/filename\*=UTF-8''([\w%\-\.]+)(?:;|$)/;
常量asciiFilenameRegex=/filename=([“'])(.*?[^\\])\1(?:;|$)/;
让fileName:string=null;
if(utf8FilenameRegex.test(处置)){
fileName=decodeURIComponent(utf8FilenameRegex.exec(disposition)[1]);
}否则{
const matches=asciiFilenameRegex.exec(处置);
if(matches!=null&&matches[2]){
fileName=匹配[2];
}
}
返回文件名;
}
几点注意:
“
)替换为。
(Chrome)控制台怎么说?为什么要设置
window.location.href=”http://localhost:8080/prj/“+data+”/“+uiid+”/getfile”代码>?这将导致浏览器离开页面并仅显示该URL。如果您已离开页面,您希望如何显示图像的缩略图?为什么需要服务器建议您将文件保存为的文件名以生成缩略图?从内容处置中获取文件名是一个问题。您无法从中获取文件类型,至少不可靠,这就是内容类型头的用途。缩略图显示将来自数据,这是一个完全独立的问题。我需要在缩略图附近显示文件名。但我可以从文件名本身filename.jpg
找到文件类型filename=matches[1]。替换(/['']/g'))
do?此解决方案不适用于以下情况:attachment;filename*=UTF-8''filename.txt。使用此正则表达式,文件名将为UTF-8filename.txt。我无法相信JavaScript有时会多么狡猾和丑陋……也无法与这样的utf8模式匹配:dis=“attachment;filename*=UTF-8''filename.pdf“
试试/filename\*?=([^']*”)([^;]*)/.exec(dis)[2]
我认为最好使用disposition.startsWith(“附件”)
而不是disposition.indexOf(“附件”)!==-1
,因为文件名可能包含附件,不能使用以下格式:内容处置:“附件;filename=document.pdf;文件名*=UTF-8''document.pdf“
添加了一个解决@AlexMWouldn提到的问题的答案,如果文件名中有分号,这不是失败吗?这是一种幼稚的方法,不推荐使用。如果文件名包含分号,则可能返回不正确的结果。缺少对filename*=UTF-8''
的支持。该解决方案适用于filename*=UTF-8''
格式您可能指的整个格式如下内容配置:“附件;filename=document.pdf;filename*=UTF-8''document.pdf”
。在说这行不通之前,请试着理解并回答!是的,从技术上讲,如果文件名本身有分号,这个解决方案将不起作用。但在大多数情况下,文件名不包含分号,所以在考虑到这个借口的情况下,它对我来说效果很好!(仍然在我的回答中添加了一个注释。)当文件名本身包含filename=
时,它也不适用于en-edge大小写。它似乎在浏览器上不起作用。
let colors = {"png": "red", "jpg": "orange"};
//this is a simple example, you can make something more beautiful
let createSVGThumbnail = extension => `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20">
<rect x="0" y="0" width="18" height="20" fill = "#FAFEFF"/>
<rect x="0" y="7" width="18" height="6" stroke="${colors[extension] || "blue"}" fill = "${colors[extension] || "blue"}"/>
<text stroke = "white" fill = "white" font-size = "6" x = "0" y = "12.5" textLength = "18">${extension.toUpperCase()}</text>
</svg>`;
...
//You can use it as HTML element background-image
let background = "data:image/svg+xml;base64," + btoa(new TextDecoder().decode(createSVGThumbnail("png")));