informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
<a href="链接" >下载</a>
Tautan file (biasanya file di server). Tautan ini biasanya dimasukkan di bilah alamat untuk melihat pratinjau, bukan untuk mengunduh lampiran.
Jika Anda ingin mengubahnya menjadi unduhan lampiran, Anda dapat memilih salah satu dari dua metode berikut:
1. Pemrosesan backend, tambahkan header respons ke backend
res.setHeader('Content-Dispostion', 'attachment', 'name.pdf')
2. Tambahkan atribut download pada tag a
<a href="链接" download="文件名" >下载</a>
Kekurangan: Saat menggunakan tag a untuk mengunduh file dalam JavaScript, unduhan browser dipicu langsung melalui peristiwa klik dari tag a. Header permintaan tidak dapat disetel karena ini adalah permintaan GET sederhana. Jika pengunduhan file ini memerlukan pembawaan token, maka tag a tidak akan efektif (tag a tidak dapat membawa token) dan akan menjadi pratinjau.
Solusi: Tag a dapat membawa cookie, jadi ada solusi lain Sebelum mengunduh file, kirimkan permintaan untuk mendapatkan token sementara dan membawanya melalui cookie. Unduhan tag a adalah unduhan streaming, yang akan membuat file server seperti air mengalir. Disimpan ke disk lokal, sehingga hasil download dapat dilihat langsung dan file tidak akan di-cache di browser.
Tulis metode untuk mendownload (intinya tetap gunakan tag a untuk mendownload)
Metode ini dapat berupa permintaan ajax, yang dapat membawa token, lalu mengonversi file server yang diminta menjadi blob, membuat tag a untuk diunduh, membuat elemen tautan virtual, dan menyimulasikan klik untuk mengunduh. Metode ini akan menempati thread front-end.
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));
}
**Jika filenya kecil, tidak apa-apa. Jika filenya besar, Anda akan mengklik untuk mendownload, tetapi tidak akan ada respon. Download akan muncul setelah beberapa menit sisi server menjadi gumpalan (res.blob () Butuh waktu yang sangat lama) sebelum pengunduhan streaming tag a dilakukan (hanya di sini refleksi interaktif pengunduhan mulai muncul di halaman)