国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

文件下載那點事

PascalXie / 1731人閱讀

摘要:不過這種方式有問題,目前查到的大部分過程都是會在服務(wù)器新建出一個文件,等下載完畢在做刪除,還沒有找到可以跨過這一步的方式。

Content-Disposition / Content-Type Content-Disposition

http 頭部的 Content-Disposition字段,規(guī)定了返回的內(nèi)容用什么形式展示

value 含義 是否默認(rèn)
inline 以網(wǎng)頁或者頁面的一部分
attachment 以附件的形式下載并保存到本地
http.createServer((req, res) => {
  res.setHeader("Content-Disposition", "attachment")
  res.end("123 - 321 - 1234567")    
})

前端需要使用window.open 形式訪問 此路由就可以實現(xiàn)文件的下載

window.open(xxxx)

或者使用 H5新屬性 a 標(biāo)簽

 點擊下載 
Content-Type
http.createServer((req, res) => {
  res.setHeader("Content-Type", "application/octet-stream")
  res.end("123 - 321 - 1234567")    
})

同上前端使用 open 或者 a標(biāo)簽進行處理

備注: 如果使用普通的請求,是不可以的,比如使用ajax

window.open

window.open 可以下載文件的原因是,瀏覽器遇到無法解析的文件就是執(zhí)行下載

當(dāng)使用瀏覽器打開文件時, 如果它無法解析,那么就會把該文件下載下來

http.createServer((req, res) => {
  const data = fs.readFileSync("./Zip.zip")
  res.end(data)    
})

拿到的data是一個buffer 對象,那么直接寫一個Buffer可以實現(xiàn)下載么

data = new Buffer("我是誰,誰是我")

嘗試后發(fā)現(xiàn),koa是可以的。但是原生直接這么寫是不行的

http.createServer((req, res) => {
  const newBuf = new Buffer("我是誰,誰是我")
  res.end(newBuf)    
})
通過接口拿到數(shù)據(jù)之后進行下載

在實際項目中,文件下載可能出現(xiàn)的場景

對于已經(jīng)在服務(wù)器存在的文件進行下載,比如圖片資源

將一些查詢數(shù)據(jù)導(dǎo)出到本地, 比如mysql查詢結(jié)果導(dǎo)出csv

對于已存在的資源,可以直接使用 上面說的 winodw.open 或者 a 標(biāo)簽進行下載,那么對于不是以文件形式存在的資源呢

data URI

經(jīng)常見到使用 data URI scheme 的是圖片, 一般為了減少http請求,會將圖片直接以base64的形式展示在html中


也可以應(yīng)用到文件下載中

router.get("/download", async (ctx, next) => {
  const newBUf = new Buffer("我是誰,誰是我")
  ctx.body = newBUf
}
axios.get(`${path}`)
.then(function ({data}) {
  let a = document.createElement("a");
  a.href = "data:text/plain;charset=utf-8," + data;
  a.download = "myfilename.png";
  a.click();
// 記得處理臨時元素 防止內(nèi)存泄漏
  a = null
})
Blob

Blob 是表示一個類文件對象,可以用它來表示一個文件

server 部分

http.createServer((req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  let end = ""
  if (req.url.includes("/down")) {
    const newBUf = new Buffer("我是誰,誰是我")
    end = newBUf
  }
  res.end(end)
}  

前端

    const xhr = new XMLHttpRequest();
    xhr.open("GET", path);
    xhr.responseType = "blob";

    xhr.onload = function () {
      const blob = xhr.response;
      const url = URL.createObjectURL(blob);
      // 通過a標(biāo)簽去下載
      const link = document.createElement("a");
      link.href = url;
      link.download = fileName;
      link.click();
      link = null
      
      URL.revokeObjectURL(url);
    };
   xhr.send();

嘗試用 window.open 方式,發(fā)現(xiàn)不可以

目前常用的各個第三方庫也支持返回內(nèi)容為blob格式

  axios.get(`${path}`, {
    responseType: "blob"
  })

或者 fetch

  fetch(path).then(res => res.blob().then(blob =>{ ... })
window.URL

createObjectURL

用 blob 對象來創(chuàng)建一個 object URL(它是一個 DOMString),我們可以用這個 object URL 來表示某個 blob 對象,這個 object URL 可以用在 a 標(biāo)簽的 href屬性上,然后觸發(fā)點擊事件,就可以下載文件了

revokeObjectURL

為了避免避免內(nèi)存泄漏,需要手動釋放創(chuàng)建的 object URL

缺點

構(gòu)建完 blob 對象后才會轉(zhuǎn)換成文件

從代碼就能看出,需要先將返回內(nèi)容轉(zhuǎn)為blob才進行下載操作,如果用戶操作的是一個很大的資源,在等待文件正式下載前,還需要一段時間等待格式的轉(zhuǎn)化

實例 將mysql數(shù)據(jù) 導(dǎo)出 csv

這邊直接用數(shù)據(jù)模擬mysql查詢結(jié)果, 在網(wǎng)上查到兩種拼接方式,肯定有其余的方案

第一種

const result = [
  ["id", "oreder", "name", "status" ],
  [1, "201904120201", "正在加載", "已完成"],
  [18, "201904120204", "測試189", "待付款"],
  [22, "201904120209", "藍(lán)田日暖", "待付款"],
]

// 可以看到 result 數(shù)組的第一組是 csv的各個字段標(biāo)題 

const data = csvData.reduce((cur, next) => `${cur + next.join(",")}
`, "")
const blob = new Blob([data]);
const url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
a = null

window.URL.revokeObjectURL(url);

第二種

const result = [
  [1, "201904120201", "正在加載", "已完成"],
  [18, "201904120204", "測試189", "待付款"],
  [22, "201904120209", "藍(lán)田日暖", "待付款"],
]

// result 就是正常的數(shù)據(jù)格式

  // 解決亂碼問題
  let dataType = "uFEFF"
  // 添加表格的頭子段
  dataType += (["  訂單編號", "用戶", "動態(tài)ID"].join(",")) 
  dataType += "
"

  csvData.forEach(item => { 
    dataType += ([item.id, item.order, item.name, item.staus].join(","))
    dataType += "
"
  })

  const blob = new Blob([dataType], {type: "text/csv"})    
如果有幾段流文件,前端需要下載拼接成一個完整文件,如何實現(xiàn)

肯定是在 server端進行文件的拼接操作,然后返回到前端下載

大致過程

const content1 = "這里是第1段文件內(nèi)容"

const content2 = "這里是第2段文件內(nèi)容"

ctx.body = { code:200, data: content1 + content2 }

前端就是上文中的blob 下載方式了

批量下載如何處理

其實這個問題是在查詢資料的過程有人提到的問題

window.open

批量寫了多個 window.open 在Chrome中 可以正常使用,但是在safari中,只能打開一個窗口,下載一個文件

轉(zhuǎn)為下載一個zip 文件

感覺如果將所有文件合并成為一個xxx.zip 然后對 這個zip文件做下載。不過這種方式有問題,目前查到的大部分過程都是會在服務(wù)器新建出一個 zip 文件,等下載完畢在做刪除,還沒有找到可以跨過這一步的方式。

參考文章

Data URI Scheme

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/103491.html

相關(guān)文章

  • 移動端鍵盤和光標(biāo)的兼容點事

    摘要:解決方法如果使用頁面數(shù)據(jù)不超過一屏禁止?jié)L動,那么即使變成了頁面也不會有什么變化。 作者:@micky思 @wupq @yewq 在H5的開發(fā)中,個人的制作頁面布局習(xí)性不同,多多少少會產(chǎn)生在真機上input的光標(biāo)和鍵盤的彈出會出現(xiàn)的各種BUG,文中整理了部分遇到的問題,歡迎新增 ios移動端輸入框上浮導(dǎo)致輸入位置偏移 問題原因:遮罩層定位為fixed,當(dāng)鍵盤彈起時,ios11以及以下...

    XboxYan 評論0 收藏0
  • 移動端鍵盤和光標(biāo)的兼容點事

    摘要:解決方法如果使用頁面數(shù)據(jù)不超過一屏禁止?jié)L動,那么即使變成了頁面也不會有什么變化。 作者:@micky思 @wupq @yewq 在H5的開發(fā)中,個人的制作頁面布局習(xí)性不同,多多少少會產(chǎn)生在真機上input的光標(biāo)和鍵盤的彈出會出現(xiàn)的各種BUG,文中整理了部分遇到的問題,歡迎新增 ios移動端輸入框上浮導(dǎo)致輸入位置偏移 問題原因:遮罩層定位為fixed,當(dāng)鍵盤彈起時,ios11以及以下...

    Kerr1Gan 評論0 收藏0
  • 移動端鍵盤和光標(biāo)的兼容點事

    摘要:解決方法如果使用頁面數(shù)據(jù)不超過一屏禁止?jié)L動,那么即使變成了頁面也不會有什么變化。 作者:@micky思 @wupq @yewq 在H5的開發(fā)中,個人的制作頁面布局習(xí)性不同,多多少少會產(chǎn)生在真機上input的光標(biāo)和鍵盤的彈出會出現(xiàn)的各種BUG,文中整理了部分遇到的問題,歡迎新增 ios移動端輸入框上浮導(dǎo)致輸入位置偏移 問題原因:遮罩層定位為fixed,當(dāng)鍵盤彈起時,ios11以及以下...

    Jackwoo 評論0 收藏0
  • 關(guān)于性能優(yōu)化的點事——函數(shù)防抖

    摘要:函數(shù)防抖場景假設(shè)網(wǎng)站有個搜索框用戶輸入文本我們會自動聯(lián)想匹配出一些結(jié)果供用戶選擇我們可能首先想到的做法就是監(jiān)聽事件然后異步查詢結(jié)果但是如果用戶快速的輸入了一串字符假設(shè)是個字符那么就會在瞬間觸發(fā)次請求這無疑不是我們想要的我們想要的是用戶停止輸 函數(shù)防抖 場景 假設(shè)網(wǎng)站有個搜索框, 用戶輸入文本我們會自動聯(lián)想匹配出一些結(jié)果供用戶選擇,我們可能首先想到的做法就是監(jiān)聽keypress事件, 然...

    Stardustsky 評論0 收藏0
  • 關(guān)于var,let,const的點事

    摘要:一直使用定義變量,的出現(xiàn)給變量定義增加了兩個大將,。聲明的變量,塊作用域,不重復(fù)聲明覆蓋,限制了變量的作用域,保證變量不會去污染全局變量,所以盡量將改為用。 一直使用var定義變量,ES6的出現(xiàn)給變量定義增加了兩個大將let,const。那它們有什么區(qū)別呢。 1、const關(guān)鍵字它的作用就是定義一個常量,一旦定義無法更改,不能重復(fù)聲明覆蓋; showImg(https://segmen...

    KavenFan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<