JS使用decodeURIComponent解码URL异常 无法正确提取filename参数
问题根因
filename不是URL的顶层查询参数,它是嵌套在response-content-disposition这个顶层查询参数的值内部的字段,直接调用urlParams.get('filename')无法命中,因为顶层参数列表里不存在名为filename的键。- 你提供的示例URL存在格式错误:
response-content-disposition参数值和后续的response-content-type参数之间缺失了查询参数分隔符&,直接解析会导致两个参数被识别为同一个参数的内容,解析结果完全错乱。 filename*=是RFC 5987规定的带编码声明的文件名字段,优先级高于普通filename字段,通用URL解析逻辑不会自动识别该字段的特殊格式规则。- 你示例代码中
decodeURIComponent("linkhere")仅对固定字符串"linkhere"做解码,没有传入实际待处理的完整URL,这行代码本身没有实际作用。
修复方案
按照参数层级逐层解析,优先识别标准filename*字段,兼容普通filename字段,解析前先修正URL格式错误:
// 填入实际待处理的完整URL let rawUrl = "https://linkhere?response-content-disposition=inline; filename=\"placeholder.jpg\"; filename*=UTF-8''placeholder.jpg response-content-type=image/jpeg&X-Amz-Algorithm=....sometextcontinueshere" // 修正URL中缺失的参数分隔符 rawUrl = rawUrl.replace(/\s+response-content-type/, '&response-content-type') const urlObj = new URL(rawUrl) // 先获取顶层的response-content-disposition参数值 const dispositionStr = urlObj.searchParams.get('response-content-disposition') let targetFilename = null // 优先匹配RFC标准的filename*字段,格式为 编码方式''编码后的文件名 const filenameStarMatch = dispositionStr.match(/filename\*=([^;]+)''([^;]+)/) if (filenameStarMatch) { targetFilename = decodeURIComponent(filenameStarMatch[2].trim()) } else { // 无filename*时匹配普通filename字段,去除包裹的引号 const normalFilenameMatch = dispositionStr.match(/filename="?([^";]+)"?/) if (normalFilenameMatch) { targetFilename = normalFilenameMatch[1].trim() } } console.log(targetFilename) // 输出: placeholder.jpg
注意:如果业务场景中
filename*的编码不是UTF-8,需要根据匹配到的编码字段(即上述正则中第一个捕获组的内容)做对应解码,绝大多数云存储签名URL场景下该编码均为UTF-8。
内容的提问来源于stack exchange,提问作者shkurta
相关产品推荐
相关产品推荐

