下载附件时能否保留原始文件名
- 内容介绍
- 相关推荐
下载帖子的附件时,蓝色预览可以看到原始文件名,但点击下载后变成了url对应的随机字符
image445×119 5.58 KB
--【壹】--:
你下载下来显示文件名就是原始的文件名的,显示的是title。
就像是超链接一样,如链接是一样的,显示可以随意
L站主页
LINUXDO
--【贰】--:
我还以为就我这样,每次下载都是随机字符,都只能手动改名才不怕之后忘了下载的是什么
--【叁】--:
用AI搓了一个脚本可以实现
// ==UserScript==
// @name Linux.do 真实文件名下载
// @namespace https://linux.do/
// @version 1.3
// @description 下载 Linux.do 附件时自动还原真实文件名
// @author qiuba
// @match https://linux.do/t/topic/*
// @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHJ4PSI0IiBmaWxsPSIjMDAwIi8+PHRleHQgeD0iMTIiIHk9IjE3IiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTQiIGZvbnQtd2VpZ2h0PSJib2xkIiBmaWxsPSIjZmZmIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5hYjwvdGV4dD48L3N2Zz4=
// @grant GM_xmlhttpRequest
// @grant GM_download
// @connect linux.do
// @run-at document-start
// ==/UserScript==
(function () {
‘use strict’;
const SHORT_URL_RE = //uploads/short-url/[A-Za-z0-9]+.\w+/;
/**
- 从 Content-Disposition 头中提取文件名
*/
function extractFilename(header) {
if (!header) return null;
let match = header.match(/filename\*\s*=\s*UTF-8''(.+?)(?:;|$)/i);
if (match) return decodeURIComponent(match[1].trim());
match = header.match(/filename\s*=\s*"(.+?)"/i);
if (match) return match[1].trim();
match = header.match(/filename\s*=\s*([^\s;]+)/i);
if (match) return match[1].trim();
return null;
}
/**
-
通过 HEAD 请求获取真实文件名,然后用该文件名下载
*/
function downloadWithRealName(url, fallbackName) {
GM_xmlhttpRequest({
method: ‘HEAD’,
url: url,
followRedirect: true,
onload: function (res) {
const disposition = res.responseHeaders
.split(‘\n’)
.find(h => h.toLowerCase().startsWith(‘content-disposition’));let filename = null;
if (disposition) {
filename = extractFilename(disposition);
}if (!filename) {
filename = fallbackName || url.split(‘/’).pop() || ‘download’;
}console.log(
[真实文件名下载] ${filename});GM_download({
url: url,
name: filename,
onerror: function (err) {
console.warn(‘[真实文件名下载] GM_download 失败,尝试 fallback’, err);
fetchAndDownload(url, filename);
}
});
},
onerror: function () {
window.open(url, ‘_blank’);
}
});
}
/**
- Fallback:fetch 下载 + Blob + 触发保存
*/
function fetchAndDownload(url, filename) {
fetch(url)
.then(r => r.blob())
.then(blob => {
const a = document.createElement(‘a’);
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(() => {
URL.revokeObjectURL(a.href);
a.remove();
}, 1000);
})
.catch(() => {
window.open(url, ‘_blank’);
});
}
/**
- 拦截点击事件
*/
document.addEventListener(‘click’, function (e) {
const anchor = e.target.closest(‘a[href]’);
if (!anchor) return;
const href = anchor.href;
if (!SHORT_URL_RE.test(href)) return;
e.preventDefault();
e.stopPropagation();
const fallbackName = anchor.textContent.trim() || null;
downloadWithRealName(href, fallbackName);
}, true);
})();
--【肆】--:
应该是响应标头没加filename=“xxx”,chrome就直接拿url末尾解析出的文件名了
下载帖子的附件时,蓝色预览可以看到原始文件名,但点击下载后变成了url对应的随机字符
image445×119 5.58 KB
--【壹】--:
你下载下来显示文件名就是原始的文件名的,显示的是title。
就像是超链接一样,如链接是一样的,显示可以随意
L站主页
LINUXDO
--【贰】--:
我还以为就我这样,每次下载都是随机字符,都只能手动改名才不怕之后忘了下载的是什么
--【叁】--:
用AI搓了一个脚本可以实现
// ==UserScript==
// @name Linux.do 真实文件名下载
// @namespace https://linux.do/
// @version 1.3
// @description 下载 Linux.do 附件时自动还原真实文件名
// @author qiuba
// @match https://linux.do/t/topic/*
// @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHJ4PSI0IiBmaWxsPSIjMDAwIi8+PHRleHQgeD0iMTIiIHk9IjE3IiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTQiIGZvbnQtd2VpZ2h0PSJib2xkIiBmaWxsPSIjZmZmIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5hYjwvdGV4dD48L3N2Zz4=
// @grant GM_xmlhttpRequest
// @grant GM_download
// @connect linux.do
// @run-at document-start
// ==/UserScript==
(function () {
‘use strict’;
const SHORT_URL_RE = //uploads/short-url/[A-Za-z0-9]+.\w+/;
/**
- 从 Content-Disposition 头中提取文件名
*/
function extractFilename(header) {
if (!header) return null;
let match = header.match(/filename\*\s*=\s*UTF-8''(.+?)(?:;|$)/i);
if (match) return decodeURIComponent(match[1].trim());
match = header.match(/filename\s*=\s*"(.+?)"/i);
if (match) return match[1].trim();
match = header.match(/filename\s*=\s*([^\s;]+)/i);
if (match) return match[1].trim();
return null;
}
/**
-
通过 HEAD 请求获取真实文件名,然后用该文件名下载
*/
function downloadWithRealName(url, fallbackName) {
GM_xmlhttpRequest({
method: ‘HEAD’,
url: url,
followRedirect: true,
onload: function (res) {
const disposition = res.responseHeaders
.split(‘\n’)
.find(h => h.toLowerCase().startsWith(‘content-disposition’));let filename = null;
if (disposition) {
filename = extractFilename(disposition);
}if (!filename) {
filename = fallbackName || url.split(‘/’).pop() || ‘download’;
}console.log(
[真实文件名下载] ${filename});GM_download({
url: url,
name: filename,
onerror: function (err) {
console.warn(‘[真实文件名下载] GM_download 失败,尝试 fallback’, err);
fetchAndDownload(url, filename);
}
});
},
onerror: function () {
window.open(url, ‘_blank’);
}
});
}
/**
- Fallback:fetch 下载 + Blob + 触发保存
*/
function fetchAndDownload(url, filename) {
fetch(url)
.then(r => r.blob())
.then(blob => {
const a = document.createElement(‘a’);
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(() => {
URL.revokeObjectURL(a.href);
a.remove();
}, 1000);
})
.catch(() => {
window.open(url, ‘_blank’);
});
}
/**
- 拦截点击事件
*/
document.addEventListener(‘click’, function (e) {
const anchor = e.target.closest(‘a[href]’);
if (!anchor) return;
const href = anchor.href;
if (!SHORT_URL_RE.test(href)) return;
e.preventDefault();
e.stopPropagation();
const fallbackName = anchor.textContent.trim() || null;
downloadWithRealName(href, fallbackName);
}, true);
})();
--【肆】--:
应该是响应标头没加filename=“xxx”,chrome就直接拿url末尾解析出的文件名了

