成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

前端實(shí)現(xiàn)文件下載

mylxsw / 2600人閱讀

摘要:之前寫(xiě)了一篇前端實(shí)現(xiàn)圖片下載,大部分場(chǎng)景下,文件下載都可以按照這個(gè)思路來(lái)實(shí)現(xiàn)。其實(shí)可以和后臺(tái)約定返回內(nèi)容,前端通過(guò)監(jiān)聽(tīng)的內(nèi)容實(shí)現(xiàn)監(jiān)聽(tīng)??v觀源碼,主要實(shí)現(xiàn)上傳,可借鑒用于下載的方案并沒(méi)有發(fā)現(xiàn)對(duì)請(qǐng)求的狀態(tài)進(jìn)行監(jiān)聽(tīng)。

之前寫(xiě)了一篇《前端實(shí)現(xiàn)圖片下載》,大部分場(chǎng)景下,文件下載都可以按照這個(gè)思路來(lái)實(shí)現(xiàn)。

但是,最近遇到了一個(gè)新的需求——POST 下載。服務(wù)端只支持 POST 請(qǐng)求,而上一篇文章中涉及的大部分場(chǎng)景都是 GET 請(qǐng)求。

服務(wù)端實(shí)現(xiàn)

以 Node + Koa2 實(shí)現(xiàn)為例,服務(wù)端返回 excel 文件流

const fs = require("fs")
const path = require("path")

module.exports = ctx => {
  ctx.set("Content-Type", "application/vnd.ms-excel")
  ctx.set("Content-Disposition", "attachment; filename=download.xlsx")
  ctx.body = fs.createReadStream(path.resolve(__dirname, "./download.xlsx"))
}
兼容性好的老方案

經(jīng)典的、兼容性好的方案可以通過(guò)構(gòu)建 Form 表單來(lái)實(shí)現(xiàn)

let uuidIndex = 0

export default (url, params, method = "post") => {
  const uuid = `TMP_FRAME_NAME__${uuidIndex++}`
  const iframe = document.createElement("iframe")
  iframe.name = uuid
  iframe.style = "display:none"
  // 無(wú)論響應(yīng)成功失敗,都會(huì)調(diào)用 onload
  // iframe.onload = success
  // iframe.onerror = fail
  document.body.appendChild(iframe)

  const form = document.createElement("form")
  form.action = url
  form.method = method
  form.target = uuid
  form.style = "display:none"
  form.enctype = "application/x-www-form-urlencoded"
  document.body.appendChild(form)

  if (params) {
    Object.keys(params).forEach(key => {
      const v = params[key]
      if (v !== undefined) {
        const input = document.createElement("input")
        input.type = "hidden"
        input.name = key
        input.value = v
        form.appendChild(input)
      }
    })
  }

  form.submit()
  document.body.removeChild(form)
  document.body.removeChild(iframe)
}
尋找新方案

產(chǎn)品提了一個(gè)需求,下載成功要提示,下載失敗也要提示。那么問(wèn)題來(lái)了,上面的老方案,不太好監(jiān)聽(tīng)這次操作是正常還是異常。(其實(shí)可以和后臺(tái)約定返回內(nèi)容,前端通過(guò)監(jiān)聽(tīng) iframe 的內(nèi)容實(shí)現(xiàn)監(jiān)聽(tīng)。)

插曲

有個(gè) jQuery 插件 jquery.form.js API 中提供了對(duì)成功和失敗的回調(diào)??v觀源碼,主要實(shí)現(xiàn) form 上傳,可借鑒用于下載的方案并沒(méi)有發(fā)現(xiàn)對(duì)請(qǐng)求的狀態(tài)進(jìn)行監(jiān)聽(tīng)。

正題

在經(jīng)歷了以上插曲后,找到一種新的方案。

在新方案中,使用了一些 HTML5 的 API,例如 Blob。所以,兼容性需要 IE 10+ 。

function download(url, name) {
  const aLink = document.createElement("a")
  aLink.download = name
  aLink.href = url
  aLink.dispatchEvent(new MouseEvent("click", {}))
}

export default (data, name, type) => {
  const blob = new Blob([data], { type })
  const url = URL.createObjectURL(blob)
  download(url, name)
}
demo 一枚
import axios from "axios"
// 上面的新方案
import download from "./download" 

document.getElementById("button").addEventListener("click", () => {
  axios.post("/download", null, {
    // 記得設(shè)置為成以 buffer 格式讀取
    responseType: "arraybuffer"
  })
  .then((res) => {
    // 從響應(yīng)頭里面讀取名字,當(dāng)然,可以自定義
    const name = res.headers["content-disposition"].replace(/.*filename=/, "")
    download(res.data, name, "application/vnd.ms-excel")
  })
  .catch((error) => {
    console.log(error)
  })
})
吐槽

segmentfault 網(wǎng)站編輯器編輯 markdown 對(duì) js 代碼塊的解析有 bug,帶了箭頭函數(shù) // 注釋就失效了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96631.html

相關(guān)文章

  • node實(shí)現(xiàn)文件下載不得不說(shuō)的那些事兒

    摘要:如果像本例中這樣的場(chǎng)景會(huì)遇到這樣一個(gè)問(wèn)題,詳見(jiàn)鏈接當(dāng)請(qǐng)求參數(shù)過(guò)長(zhǎng)或?yàn)榱税踩托枰玫较螺d。寫(xiě)到這里自己都忍不住想錘自己,給自己挖坑不說(shuō),這樣來(lái)回請(qǐng)求下載,流量,真的是敗家。 這幾天一直在做遠(yuǎn)程文件下載的事,現(xiàn)在總算有了解決,特來(lái)記錄一下踩過(guò)的坑和想揍自己的心 需求 應(yīng)用場(chǎng)景是這樣的,底層邏輯數(shù)據(jù)請(qǐng)求接口是由Java寫(xiě)的,也就是說(shuō)原始文件存在Java服務(wù)端,返回時(shí)有加密措施 由于工作...

    Coly 評(píng)論0 收藏0
  • 簡(jiǎn)談文件下載的三種方式

    摘要:一前言本文章將以報(bào)表下載為例,給大家介紹三種文件下載的方式。通過(guò)二進(jìn)制數(shù)據(jù)流的方式下載這種方式是我目前采用的方式,用于處理報(bào)表下載。缺點(diǎn)對(duì)于數(shù)據(jù)量不大的文件,這種方式是可行的。 一、前言 本文章將以excel報(bào)表下載為例,給大家介紹三種文件下載的方式。 原文地址:簡(jiǎn)談文件下載的三種方式 | Rychou 二、正文 1. 通過(guò)服務(wù)器文件地址下載 這是最常見(jiàn)的文件下載方式,大多數(shù)網(wǎng)站的音頻...

    lsxiao 評(píng)論0 收藏0
  • 簡(jiǎn)談文件下載的三種方式

    摘要:一前言本文章將以報(bào)表下載為例,給大家介紹三種文件下載的方式。通過(guò)二進(jìn)制數(shù)據(jù)流的方式下載這種方式是我目前采用的方式,用于處理報(bào)表下載。缺點(diǎn)對(duì)于數(shù)據(jù)量不大的文件,這種方式是可行的。 一、前言 本文章將以excel報(bào)表下載為例,給大家介紹三種文件下載的方式。 原文地址:簡(jiǎn)談文件下載的三種方式 | Rychou 二、正文 1. 通過(guò)服務(wù)器文件地址下載 這是最常見(jiàn)的文件下載方式,大多數(shù)網(wǎng)站的音頻...

    2i18ns 評(píng)論0 收藏0
  • 實(shí)現(xiàn)前后端分離的心得

    摘要:實(shí)現(xiàn)前后端分離的心得對(duì)目前的來(lái)說(shuō),前后端分離已經(jīng)變得越來(lái)越流行了,越來(lái)越多的企業(yè)網(wǎng)站都開(kāi)始往這個(gè)方向靠攏。前后端工作分配不均。 實(shí)現(xiàn)前后端分離的心得 對(duì)目前的web來(lái)說(shuō),前后端分離已經(jīng)變得越來(lái)越流行了,越來(lái)越多的企業(yè)/網(wǎng)站都開(kāi)始往這個(gè)方向靠攏。那么,為什么要選擇前后端分離呢?前后端分離對(duì)實(shí)際開(kāi)發(fā)有什么好處呢? 為什么選擇前后端分離 在以前傳統(tǒng)的網(wǎng)站開(kāi)發(fā)中,前端一般扮演的只是切圖的工作...

    zilu 評(píng)論0 收藏0
  • 前端UI組件復(fù)用工具

    摘要:代碼復(fù)用總是程序員喜聞樂(lè)見(jiàn)的,前端組件化的最終目的就是復(fù)用,今天我們就將深入探討如何實(shí)現(xiàn)組件的復(fù)用。 懶是第一生產(chǎn)力。 代碼復(fù)用總是程序員喜聞樂(lè)見(jiàn)的,前端組件化的最終目的就是復(fù)用,今天我們就將深入探討如何實(shí)現(xiàn)UI組件的復(fù)用。 通常我們所說(shuō)的組件往往是包含業(yè)務(wù)邏輯的前端組件,而這類(lèi)組件實(shí)際上很難實(shí)現(xiàn)廣義上的復(fù)用,頂多能在同一條業(yè)務(wù)線(xiàn)上復(fù)用一下,但UI組件就不一樣了,沒(méi)有了業(yè)務(wù)的約束,只在...

    xuxueli 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<