2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
<a href="链接" >下载</a>
Ein Dateilink (normalerweise eine Datei auf dem Server). Dieser Link wird im Allgemeinen zur Vorschau in die Adressleiste eingegeben, nicht zum Herunterladen eines Anhangs.
Wenn Sie es in einen Anhang-Download umwandeln möchten, können Sie eine der beiden folgenden Methoden wählen:
1. Backend-Verarbeitung: Fügen Sie dem Backend einen Antwortheader hinzu
res.setHeader('Content-Dispostion', 'attachment', 'name.pdf')
2. Fügen Sie das Download-Attribut zum a-Tag hinzu
<a href="链接" download="文件名" >下载</a>
Nachteile: Bei Verwendung des a-Tags zum Herunterladen einer Datei in JavaScript wird der Browser-Download direkt durch das Klickereignis des a-Tags ausgelöst und der Anforderungsheader kann nicht festgelegt werden, da es sich um eine einfache GET-Anfrage handelt. Wenn für den Download dieser Datei ein Token erforderlich ist, ist das A-Tag nicht wirksam (das A-Tag kann kein Token tragen) und wird zu einer Vorschau.
Lösung: Das A-Tag kann Cookies übertragen, daher gibt es eine andere Lösung: Senden Sie vor dem Herunterladen der Datei eine Anfrage, um ein temporäres Token zu erhalten und es über das Cookie zu übertragen. Beim A-Tag-Download handelt es sich um einen Streaming-Download, der die Dateien vom Server erstellt Wird wie fließendes Wasser auf der lokalen Festplatte gespeichert, sodass der Download direkt angezeigt werden kann und die Datei nicht im Browser zwischengespeichert wird.
Schreiben Sie eine Methode zum Herunterladen (verwenden Sie im Wesentlichen immer noch das a-Tag zum Herunterladen).
Diese Methode kann eine Ajax-Anfrage sein, die ein Token übertragen und dann die angeforderte Serverdatei in einen Blob konvertieren, ein Tag zum Herunterladen erstellen, ein virtuelles Linkelement erstellen und einen Klick zum Herunterladen simulieren kann. Diese Methode belegt den Front-End-Thread.
import fetch from 'isomorphic-fetch';
const exportFile = (url, options) => {
const projectId = sessionStorage.getItem(PROJECT_ID);
const downLoadURL = projectId ? BATCH_ACTION_URL_PREFIX.V2 : BATCH_ACTION_URL_PREFIX.V1;
const defaultOptions = {
credentials: 'same-origin',
};
const newOptions = { ...defaultOptions, ...options };
if (
newOptions.method === 'POST' ||
newOptions.method === 'PUT' ||
newOptions.method === 'DELETE'
) {
const projectId = sessionStorage.getItem(PROJECT_ID);
const appId = sessionStorage.getItem(APP_ID);
const shopId = sessionStorage.getItem(SHOP_ID);
const params = {};
projectId && Object.assign(params, { projectId });
appId && Object.assign(params, { appId });
shopId && Object.assign(params, { shopId });
newOptions.body = { ...newOptions.body, ...params };
if (!(newOptions.body instanceof FormData)) {
newOptions.headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
...newOptions.headers,
};
} else {
// newOptions.body is FormData
newOptions.headers = {
Accept: 'application/json',
...newOptions.headers,
};
}
}
const token = window.localStorage.getItem(TOKEN);
if (token) {
newOptions.headers = {
'X-Authorization': `Bearer ${token}`,
...newOptions.headers,
};
}
const lang = localStorage.getItem(LOCALE_KEY);
if (lang) {
newOptions.headers = {
'Accept-Language': lang,
...newOptions.headers,
};
}
const requestURL = `${downLoadURL}/${url}`;
return request(requestURL, newOptions).then(res => {
let filename;
if (res.headers) {
filename = (
res.headers.get('Content-Disposition') || res.headers.get('content-disposition')
).split('attachment;filename=')[1];
}
if (res.blob) {
res.blob().then(blob => {
var alink = document.createElement('a');
alink.style.display = 'none';
alink.target = '_blank';
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// 兼容IE/Edge
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
alink.href = window.URL.createObjectURL(blob);
alink.download = filename;
}
document.body.appendChild(alink);
alink.click();
URL.revokeObjectURL(alink.href); // 释放URL 对象
document.body.removeChild(alink);
});
return res;
} else {
if (res.code === 0) {
return res;
} else {
message.warning(res.message);
}
}
});
};
export default exportFile;
export default function request(url: string, options: Object) {
const defaultOptions = {
credentials: 'same-origin',
};
const newOptions = { ...defaultOptions, ...options };
if (
newOptions.method === 'POST' ||
newOptions.method === 'PUT' ||
newOptions.method === 'DELETE' ||
newOptions.method === 'PATCH'
) {
if (!(newOptions.body instanceof FormData)) {
newOptions.headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
...newOptions.headers,
};
newOptions.body = JSON.stringify(newOptions.body);
} else {
// newOptions.body is FormData
newOptions.headers = {
Accept: 'application/json',
...newOptions.headers,
};
}
}
return fetch(url, newOptions).then(response => checkStatus(response, url, options));
}
**Wenn die Datei klein ist, ist sie in Ordnung. Wenn Sie auf „Download“ klicken, wird nach einigen Minuten keine Antwort angezeigt serverseitig in einen Blob (res.blob()) Es dauerte sehr lange, bis der Streaming-Download des a-Tags durchgeführt wurde (erst hier begann die interaktive Reflexion des Downloads auf der Seite zu erscheinen)