angular2/angular4 如何通過(guò)$http的post方法請(qǐng)求下載二進(jìn)制的Excel文件

下面給大家介紹一下我遇到的一個(gè)坑,如果你也遇到了,那恭喜你,你一定能找到答案:angular2/angular4 如何通過(guò)$http的post方法請(qǐng)求下載二進(jìn)制的Excel文件? (angular1自行百度)

問(wèn)題描述:

后臺(tái)返回的是一個(gè)二進(jìn)制的Excel流,請(qǐng)求頭如下:

Access-Control-Allow-Origin:*

Cache-Control:private

Content-Disposition:attachment;filename=%E9%A9%BE%E9%A9%B6%E5%91%98%E8%AF%84%E5%88%86.xlsx

Content-Type:application/vnd.ms-excel; charset=UTF-8

Date:Thu, 15 Jun 2017 03:19:11 GMT

Server:Microsoft-IIS/8.5

Transfer-Encoding:chunked

X-AspNet-Version:4.0.30319

X-Powered-By:ASP.NET

給的請(qǐng)求方式是post,然后帶一堆的參數(shù),現(xiàn)在求如何請(qǐng)求?

當(dāng)時(shí)覺(jué)得后臺(tái)應(yīng)該是返回的是一個(gè)Excel文件下載的地址,于是按照正常的請(qǐng)求發(fā)起請(qǐng)求,結(jié)果是然并卵,報(bào)錯(cuò)了,返回?cái)?shù)據(jù)如下:



返回結(jié)果是一個(gè)二進(jìn)制流,還會(huì)有一個(gè)請(qǐng)求失敗的提示

排除后端問(wèn)題,那前端應(yīng)該怎么請(qǐng)求呢?

當(dāng)時(shí)想到的第一種方式是修改響應(yīng)頭:

Content-Type:application/vnd.ms-excel; charset=UTF-8

原來(lái)的響應(yīng)頭是Content-Type: application/json,改成xsl對(duì)應(yīng)的二進(jìn)制響應(yīng)頭應(yīng)該就沒(méi)錯(cuò)了吧,結(jié)果依然是然并卵,直接給我報(bào)500錯(cuò)誤

于是乎,決定谷歌之,百度之,發(fā)現(xiàn)處理這種辦法的大多數(shù)是這樣的:

$http({

url: 'your/webservice',

method: "POST",

data: json, //this is your json data string

headers: {

'Content-type': 'application/json'

},

responseType: 'arraybuffer'

}).success(function (data, status, headers, config) {

var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});

var objectUrl = URL.createObjectURL(blob);

window.open(objectUrl);

}).error(function (data, status, headers, config) {

//upload failed

});

基本上大部分方法跟上面的大同小異,于是按著這個(gè)方法試了試,其中的重點(diǎn)配置是 responseType: 'arraybuffer', 因?yàn)閍ngular的http模塊里面有對(duì)responseType有定義:

responseType: ResponseContentType | null;

找到ResponseContentType:

export declare enum ResponseContentType {

Text = 0,

Json = 1,

ArrayBuffer = 2,

Blob = 3,

}

原來(lái)它還有這幾個(gè)參數(shù),那ArrayBuffer 對(duì)應(yīng)就是responseType: 2, 依然是沒(méi)有用,結(jié)果跟直接用post請(qǐng)求一樣

如果你也經(jīng)歷了這些,往下看吧!

這是我在想,ResponseContentType 里面的其他的屬性都是干嘛的, 前面2個(gè)很好理解,一個(gè)是文本格式的, 一個(gè)是json格式的,那ArrayBuffer和Blob是什么意思呢?我只是簡(jiǎn)單的將一下,想深入了解,可以看看張?chǎng)涡竦?理解DOMString冕臭、Document才睹、FormData蛛砰、Blob肤无、File蕉世、ArrayBuffer數(shù)據(jù)類型

ArrayBuffer表示二進(jìn)制數(shù)據(jù)的原始緩沖區(qū)见坑,該緩沖區(qū)用于存儲(chǔ)各種類型化數(shù)組的數(shù)據(jù),ArrayBuffer是二進(jìn)制數(shù)據(jù)通用的固定長(zhǎng)度容器琼蚯。

Blob表示二進(jìn)制大對(duì)象,專門存放二進(jìn)制數(shù)據(jù)违施。

額,聽(tīng)不懂叹话?可以這么理解偷遗,ArrayBuffer就是作為數(shù)據(jù)源提前寫入在內(nèi)存中,就是提前釘死在某個(gè)區(qū)域驼壶,長(zhǎng)度也固定氏豌,萬(wàn)年不變,Blob是個(gè)更高一級(jí)的大分類热凹,包含ArrayBuffer泵喘,還有更多;

還有一種理解就是XMLHttpRequest 第二版允許服務(wù)器返回二進(jìn)制數(shù)據(jù)般妙,這時(shí)分成兩種情況纪铺。如果明確知道返回的二進(jìn)制數(shù)據(jù)類型,可以把返回類型(responseType)設(shè)為arraybuffer碟渺;如果不知道鲜锚,就設(shè)為blob。

反正不管怎么樣吧苫拍,試一試blob芜繁,于是就有我最終的代碼:

download(url?:string, form?:any){

this.downloadHeader;

return this.http.post(url, form, this.options).map(res => res.json).catch(this.handleError);

}

downloadHeader{

if (localStorage.getItem(environment.local_storage_account)) {

this.headers = new Headers({'token': JSON.parse(localStorage.getItem(environment.local_storage_account)).Token });

this.options = new RequestOptions({ headers: this.headers, responseType: 3 });

}

}

每個(gè)人的代碼寫法不一樣,請(qǐng)忽略其他的,只關(guān)注responseType: 3

最后返回的response是:

Blob {size: 4384, type: "application/vnd.ms-excel"}

那就可以用大家常用的blob方法來(lái)下載了:

var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});

var objectUrl = URL.createObjectURL(blob);

window.open(objectUrl);

這里有一個(gè)問(wèn)題,就是很多瀏覽器可能會(huì)墻掉彈窗,導(dǎo)致你的文件沒(méi)法正常下載,所以我們用a標(biāo)簽的形式來(lái)下載,思路就是成功后新建一個(gè)帶下載地址的a標(biāo)簽,然后被動(dòng)觸發(fā)點(diǎn)擊:

var blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});

var objectUrl = URL.createObjectURL(blob);

var a = document.createElement('a');

document.body.appendChild(a);

a.setAttribute('style', 'display:none');

a.setAttribute('href', objectUrl);

a.setAttribute('download', fileName);

a.click;

URL.revokeObjectURL(objectUrl);

結(jié)束后釋放url,好了,大概的思路就是這樣了,如果你還有什么不明白的,歡迎給我留言,我會(huì)盡快給你回復(fù)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绒极,隨后出現(xiàn)的幾起案子骏令,更是在濱河造成了極大的恐慌,老刑警劉巖垄提,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榔袋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡铡俐,警方通過(guò)查閱死者的電腦和手機(jī)凰兑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)审丘,“玉大人聪黎,你說(shuō)我怎么就攤上這事”感簦” “怎么了稿饰?”我有些...
    開(kāi)封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)露泊。 經(jīng)常有香客問(wèn)我喉镰,道長(zhǎng),這世上最難降的妖魔是什么惭笑? 我笑而不...
    開(kāi)封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任侣姆,我火速辦了婚禮生真,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捺宗。我一直安慰自己柱蟀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布蚜厉。 她就那樣靜靜地躺著长已,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昼牛。 梳的紋絲不亂的頭發(fā)上术瓮,一...
    開(kāi)封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音贰健,去河邊找鬼胞四。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伶椿,可吹牛的內(nèi)容都是我干的辜伟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脊另,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼导狡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起尝蠕,我...
    開(kāi)封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎载庭,沒(méi)想到半個(gè)月后看彼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡囚聚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年靖榕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顽铸。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茁计,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谓松,到底是詐尸還是另有隱情星压,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布鬼譬,位于F島的核電站娜膘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏优质。R本人自食惡果不足惜竣贪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一军洼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧演怎,春花似錦匕争、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至畏纲,卻和暖如春扇住,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗胀。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工艘蹋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人票灰。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓女阀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親屑迂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浸策,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)惹盼,斷路器庸汗,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • http://www.jb51.net/article/29950.htm 文件后綴MIME備注 *.avivid...
    ink9979閱讀 20,847評(píng)論 0 0
  • 本文詳細(xì)介紹了 XMLHttpRequest 相關(guān)知識(shí),涉及內(nèi)容: AJAX手报、XMLHTTP蚯舱、XMLHttpReq...
    semlinker閱讀 13,657評(píng)論 2 18
  • form表單提交 傳統(tǒng)的form表單提交只需要一個(gè)form標(biāo)簽,指定action掩蛤、method='POST'枉昏,并期...
    zenggo閱讀 4,408評(píng)論 0 50
  • 當(dāng)你決定喜歡一個(gè)人的時(shí)候,也意味著你開(kāi)始失去她......
    5adc213b1d02閱讀 113評(píng)論 0 0