如何从内容描述中获取文件名

10 浏览
0 Comments

如何从内容描述中获取文件名

我通过ajax下载了一个文件。如何从content-disposition中获取文件名和文件类型,并显示缩略图。我找到了很多搜索结果,但是找不到正确的方法。\n

$(".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);     
    }
});

\n控制台输出:\ninline; filename=demo3.png\n

0
0 Comments

问题出现的原因是需要从content-disposition中获取文件名,但是content-disposition的格式有多种可能,包括UTF-8编码和ASCII编码。为了解决这个问题,提供了一个代码示例,可以通过正则表达式从content-disposition中提取文件名。

解决方法如下:

1. 首先定义两个正则表达式,分别用于匹配UTF-8编码和ASCII编码的文件名。其中,UTF-8编码的正则表达式为/filename\*=UTF-8''([\w%\-\.]+)(?:; ?|$)/i,ASCII编码的正则表达式为/^filename=(["']?)(.*?[^\\])\1(?:; ?|$)/i

2. 如果content-disposition中匹配到了UTF-8编码的文件名,则使用decodeURIComponent()函数对其进行解码,并将解码后的文件名赋值给fileName变量。

3. 如果content-disposition中没有匹配到UTF-8编码的文件名,则使用ASCII编码的正则表达式进行匹配。为了防止ReDos攻击,先将content-disposition转换为小写,并找到第一个出现filename=的位置。然后从该位置开始切割字符串,并使用ASCII编码的正则表达式进行匹配。如果匹配成功,并且匹配结果的第二个分组存在,则将其赋值给fileName变量。

4. 最后,返回文件名fileName

需要注意的几点是:

1. 如果content-disposition中同时存在UTF-8编码和ASCII编码的文件名,将使用UTF-8编码的文件名。

2. 下载文件时,浏览器可能会进一步修改文件名,例如将某些字符替换为下划线。

3. ASCII编码的正则表达式适用于带引号的文件名,但也支持不带引号的文件名。在这种情况下,它将filename=之后,下一个;或者header值的末尾之前的所有文本作为文件名。

4. 代码示例中没有清理路径信息。如果你正在使用这段代码保存网站上的文件,浏览器会处理这个问题。但如果在Node.js应用程序等环境中使用,务必根据操作系统清理路径信息,只保留文件名,否则可能会使用精心构造的文件名来覆盖系统文件。

在处理content-disposition时,由于其格式的多样性,需要使用正则表达式来提取文件名。通过匹配UTF-8编码和ASCII编码的文件名,可以从content-disposition中获取到正确的文件名。在代码实现时,需要注意一些细节,如优先使用UTF-8编码的文件名、处理特殊字符、防止ReDos攻击等。

0
0 Comments

问题的原因是在从content-disposition中获取文件名时,存在一些特殊情况没有考虑到,例如文件名中包含分号(;)或者包含特殊字符。这可能导致获取到的文件名不正确。

解决方法是对代码进行改进,使用更加健壮的方法来获取文件名。可以使用正则表达式或者其他字符串处理方法来提取文件名。另外,可以考虑使用现成的库或者工具来处理content-disposition,以确保获取到的文件名是正确的。

以下是对代码的改进示例:

var contentDisposition = xhr.getResponseHeader('content-disposition');
var pattern = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = pattern.exec(contentDisposition);
var fileName = matches[1].replace(/['"]/g, '');

这样的改进可以处理更多的情况,包括文件名中包含分号或者特殊字符的情况。通过使用正则表达式匹配文件名,并且去除多余的引号,可以确保获取到的文件名是正确的。

需要注意的是,为了保证代码的健壮性,仍然需要根据具体的情况进行测试和调整。不同的服务器或者文件类型可能会有不同的content-disposition格式,需要适配不同的情况来获取正确的文件名。

总之,通过对代码的改进和使用更加健壮的方法,可以解决从content-disposition中获取文件名的问题,确保获取到的文件名是正确的。这样可以更好地处理文件下载或者其他涉及到文件名的操作。

0
0 Comments

如何从内容中获取文件名?

有时候我们需要从服务器响应中获取附件的文件名。以下是一个示例:

// 设置响应头
response.setHeader("Content-Disposition", "attachment;filename=XYZ.csv");

在JavaScript中,我们可以通过以下方式获取文件名:

function(response, status, xhr){
    var filename = "";
    var disposition = xhr.getResponseHeader('Content-Disposition');
    if (disposition && disposition.indexOf('attachment') !== -1) {
        var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        var matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) { 
          filename = matches[1].replace(/['"]/g, '');
        }
    }
}

如果需要使用`inline`而不是`attachment`,可以使用以下代码:

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, '');
        }
    }
}

这个解决方案无法处理类似于`attachment; filename*=UTF-8''filename.txt`这样的情况。使用这个正则表达式,文件名将变成`UTF-8filename.txt`。为了解决这个问题,可以使用以下正则表达式:

/filename\*?=([^']*'')?([^;]*)/.exec(disposition)[2]

另外,为了更好地匹配UTF-8编码的文件名,可以使用以下正则表达式:

(filename\*=UTF-8''|filename=)(.+\b)

以上是从内容中获取文件名的解决方法。

0