Недавно я был вовлечен в срочный проект.Приближался китайский Новый год, период строительства был напряженным, а дизайн продукта был относительно грубым.Я столкнулся с небольшой проблемой!
Требования следующие: нажмите кнопку загрузки, чтобы загрузить несколько zip-файлов в пакетном режиме, например, нажмите кнопку, серверная часть вернет массив URL-адресов для загрузки, а затем интерфейс должен инициировать загрузку одновременно.
Я думал, что это просто, пройтись по этому массиву, затем смоделировать ссылку и загрузить каждый URL-адрес, поэтому появляется следующий код:
// 下载函数
const download = (link: string)=> {
const el = getLinkNodeElement()
el.setAttribute('href', link)
triggerClick(el)
}
// 创建 a 链接
const getLinkNodeElement = () => {
const id = 'node-download'
let el = document.getElementById(id)
if (!el) {
el = document.createElement('a')
el.setAttribute('id', id)
el.setAttribute('target', '_blank')
el.setAttribute('rel', 'noopener')
document.body.appendChild(el)
}
return el
}
// 模拟点击 a 链接
const triggerClick = (node: HTMLElement) => {
try {
if (document.createEvent) {
const evt = document.createEvent('MouseEvents')
evt.initEvent('click', true, false)
node.dispatchEvent(evt)
} else if ((document as any).createEventObject) {
(node as any).fireEvent('onclick')
}
} catch (e) {
node.click()
}
}
// 获取地址,遍历,批量下载
const downloadZip = async () => {
await bookListVM.getZips() // 获取zips 的下载地址
bookListVM.zipUrlList.forEach((list) => {
download(list.url) // 遍历下载每个url
})
}
Я думал, что дело сделано, а потом после проверки я тупил Каждый раз успешно скачивалось только одно, а остальные блокировались браузером.
Потому что адрес загрузки и текущая система не находятся в одном домене! ! Это механизм безопасности браузера.
Разве не забавно, что вам нужно всегда разрешать это всплывающее окно, если вам нужно продолжить загрузку? Клиенты не заметят это место!
Даже если вы это заметите, вы можете не захотеть допустить этого, а вдруг это небезопасно!
И эта загрузка, страница все еще трясется, это решение считается расточительством.
Все не так просто, переверните план и начните сначала!
Только подумайте, как обойти перехват безопасности браузера?
ответ:Сначала откройте новую пустую страницу, браузер никогда не заблокирует ее, а затем установите страницу в качестве нашего адреса загрузки.
Ну, просто делай, что говоришь, а потом будет следующий код:
const download = (url: string) => {
const win = window.open()
win.src = url
}
// 获取地址,遍历,批量下载
const downloadZip = async () => {
await bookListVM.getZips() // 获取zips 的下载地址
bookListVM.zipUrlList.forEach((list) => {
download(list.url) // 遍历下载每个url
})
}
Как только закончил писать, обнаружил проблему, это не правильно, я хочу открыть более одной страницы, у меня пачками запускается загрузка! Я выскочил на пустую страницу, как я могу продолжать открывать другие пустые страницы? ? ?
После некоторого замешательства кажется, что это все еще не работает.Похоже, проблема не так проста!
Однако я уже согласился на тест, и он будет сделан через полчаса, кажется, осталось всего десять минут, так что я не могу дать пощечину! !
Подумав еще раз, должен же быть какой-то способ. Внезапно я вспомнил, почему скачивание должно быть ссылкой. Эта идея тупиковая. Что еще я могу начать качать?
Тогда я подумалiframe
, он также может нестиurl
Да, а скачать нельзя? Этот ярлык, который мне не нравится видеть, я не ожидал, что сегодня он спасет мне жизнь.
Затем идет следующий код:
const download = (url) => {
var iframe = document.createElement('iframe') // 先创建一个iframe 标签
iframe.style.display = 'none' // 不能在页面中被看到,把他隐藏起来,不影响我们使用啊
iframe.style.height = '0px' // 给他个0的高度,免得影响页面布局
iframe.src = url // 关联上我们的下载地址
document.body.appendChild(iframe) // 把他绑定在body上才能发挥作用,不然就能孤魂野码了
setTimeout(() => {
iframe.remove() // 实在是无奈之举,iframe 没有onload事件,只能放在setTimeout里清除了,时间稍微大一点,免得zip包太大还没有下载完。
}, 5000)
}
// 获取地址,遍历,批量下载
const downloadZip = async () => {
await bookListVM.getZips() // 获取zips 的下载地址
bookListVM.zipUrlList.forEach((list) => {
download(list.url) // 遍历下载每个url
})
}
Закончить работу, выполнить, осталась еще одна минута, протестировать, чтобы увидеть эффект,
Нажмите «Загрузить», в браузере появится запрос, разрешить ли загрузку нескольких файлов (это будет предложено только один раз), нажмите «Разрешить», загрузка прошла успешно, отлично!
Я скоро еду домой на Китайский Новый год. К счастью, я не напортачил с этим, а то было бы мудро подмести пол~
Перенеси тест, иди домой на китайский Новый год.