查理豪 發表於 2020-4-10 18:11:00

Js React中post方式下载文件/get方式下载文件

<p><span style="font-size: 15px"><strong>一.GET方式下载</strong></span></p>
<p><span style="font-size: 14px">方法一:</span></p>
<div class="cnblogs_code">
<pre>&lt;a href={systemPdf} download="application/pptx" target="_blank"&gt;下载&lt;/a&gt;</pre>
</div>
<p><span style="font-size: 14px">方法二:</span></p>
<div class="cnblogs_code">
<pre>downloadHandler = () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
   const url </span>= '../action?id=3'<span style="color: rgba(0, 0, 0, 1)">
   window.location.href </span>=<span style="color: rgba(0, 0, 0, 1)"> url
}
</span>&lt;span onClick={<span style="color: rgba(0, 0, 255, 1)">this</span>.downloadHandler}&gt;下载&lt;/span&gt; </pre>
</div>
<p><strong>缺点</strong>:<span style="color: rgba(0, 0, 0, 1)">get请求参数数据量较小时可以使用,但如果请求参数数据量较大时,一般使用post</span></p>
<p><span style="font-size: 15px"><strong>二.POST方式下载</strong></span></p>
<div class="cnblogs_code">
<pre>import React from 'react'<span style="color: rgba(0, 0, 0, 1)">;
const Ajax </span>= require('axios'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">server---start</span>
export <span style="color: rgba(0, 0, 255, 1)">function</span> request(url, options, isDemo = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">) {<br>
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可删除----开始 只为演示用</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isDemo) {
      let response </span>=<span style="color: rgba(0, 0, 0, 1)"> {
            data: {},
            fileName: </span>'demo.xlsx'<span style="color: rgba(0, 0, 0, 1)">,
            success: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
            headers: { </span>'content-type': 'application/octet-stream', 'content-disposition': 'la=1;fileName=demo.xlsx'<span style="color: rgba(0, 0, 0, 1)"> },
            responseType: options.responseType
      }
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (response.headers['content-type'] === 'application/octet-stream'<span style="color: rgba(0, 0, 0, 1)">) {
            let fileName </span>= decodeURI(response.headers['content-disposition'].split(';').split('='))
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> { data: response.data, success: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">, fileName, }
      }
   }<br><br>   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可删除----结束<br>   <br>  <span style="color: rgba(0, 0, 0, 1)">let contentType = null;</span><br><span style="color: rgba(0, 0, 0, 1)">   let fileName = null;</span><br></span>   Ajax.interceptors.response.use(response =&gt; {<br>      if(response.headers['content-type'] === 'application/octet-stream'){<br>      contentType = true;<br>      fileName = docodeURL(response.headers['content-disposition'].split(';').split('='));<br>      return response<br>     }<br>   },error =&gt; {<br>    console.log('error', error)<br>   })
    <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Ajax({
      method: options.method </span>|| "POST"<span style="color: rgba(0, 0, 0, 1)">, <span style="color: rgba(51, 153, 102, 1)">//请求方式</span>
      url: url, <span style="color: rgba(51, 153, 102, 1)">//下载地址</span>
      data: options.data </span>||<span style="color: rgba(0, 0, 0, 1)"> {},<span style="color: rgba(51, 153, 102, 1)"> //请求内容</span></span><span style="color: rgba(0, 0, 0, 1)">
      responseType: options.responseType </span>|| 'arraybuffer' <span style="color: rgba(0, 0, 0, 1)">
    }).then((res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (contentType) {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> { data: res.data, success: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">, fileName }
      }
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (res.success) {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> { data: res.data, success: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">, }
      }
    })
};

export async </span><span style="color: rgba(0, 0, 255, 1)">function</span> downloadQuery(data, responseType = 'arraybuffer'<span style="color: rgba(0, 0, 0, 1)">) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> request("/erp/api/query/data", { method: "POST"<span style="color: rgba(0, 0, 0, 1)">, data, responseType });
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">server---end</span>
<span style="color: rgba(0, 0, 0, 1)">
class Demo extends React.Component {

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">modal---start</span>
    dowmloadQuery = async (data) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const res </span>=<span style="color: rgba(0, 0, 0, 1)"> await downloadQuery(data);</span><span style="background-color: rgba(136, 136, 136, 1); color: rgba(51, 153, 102, 1)"><br></span>      <span style="color: rgba(51, 153, 102, 1)">//type:'application/.....'这里是xlsx的类型</span>
      let blob = <span style="color: rgba(0, 0, 255, 1)">new</span> Blob(, { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
      <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(blob, res.fileName)
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
            let downloadElement </span>= document.createElement('a'<span style="color: rgba(0, 0, 0, 1)">);
            let href </span>= window.URL.createObjectURL(blob); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建下载的链接</span>
            downloadElement.href =<span style="color: rgba(0, 0, 0, 1)"> href;
            downloadElement.download </span>= res.fileName; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 下载后文件名</span>
<span style="color: rgba(0, 0, 0, 1)">            document.body.appendChild(downloadElement);
            downloadElement.click(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 点击下载</span>
            document.body.removeChild(downloadElement); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 下载完成移除元素</span>
            window.URL.revokeObjectURL(href); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 释放掉blob对象</span>
<span style="color: rgba(0, 0, 0, 1)">      }
    };
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">modal---end</span>

    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">view---start</span>
    render = () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
            </span>&lt;div&gt;
                &lt; button onClick={<span style="color: rgba(0, 0, 255, 1)">this</span>.dowmloadQuery}&gt;点击并下载&lt;/button&gt;
            &lt;/div&gt;);
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">view---end</span>
<span style="color: rgba(0, 0, 0, 1)">}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> Demo;</pre>
</div>
<p>点击结果如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/1853661/202004/1853661-20200410174652150-266430089.png"></p>
<p>&nbsp;</p>
<p><span style="color: rgba(0, 0, 0, 1)"><strong>注意:</strong></span></p>
<ol>
<li><span style="color: rgba(0, 0, 0, 1)">直接通过ajax的post的方式<span style="color: rgba(0, 128, 0, 1)">无法调用浏览器的下载功能</span></span></li>
<li><span style="color: rgba(0, 0, 0, 1)">请求时r<span style="color: rgba(0, 128, 0, 1)">esponseType</span>必须设置为:<span style="color: rgba(0, 128, 0, 1)">'arraybuffer'</span>,<span style="color: rgba(0, 128, 0, 1)">后端</span>一般返回的<span style="color: rgba(0, 128, 0, 1)">'content-type': 'application/octet-stream'</span></span></li>
</ol>
<p><span style="font-size: 15px"><strong><span style="color: rgba(0, 0, 0, 1)">三:blob格式导出/下载文件</span></strong></span></p>
<p>blob流导出/下载相关功能,其中<span style="color: rgba(0, 128, 0, 1)">需要导出excel、csv、word、zip压缩文件</span>之类的,在导出/下载相应的文件类需要知道对应的<span style="color: rgba(0, 128, 0, 1)">content-type</span>属性,</p>
<table style="height: 157px; width: 714px" border="1" cellspacing="0" cellpadding="0" align="left">
<tbody>
<tr>
<td>后缀</td>
<td>MIME Type</td>
</tr>
<tr>
<td>.doc</td>
<td>application/msword</td>
</tr>
<tr>
<td>.docx</td>
<td>application/vnd.openxmlformats-officedocument.wordprocessingml.document</td>
</tr>
<tr>
<td>.xls</td>
<td>application/vnd.ms-excel</td>
</tr>
<tr>
<td>.xlsx</td>
<td>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</td>
</tr>
<tr>
<td>.ppt</td>
<td>application/vnd.ms-powerpoint</td>
</tr>
<tr>
<td>.pptx</td>
<td>application/vnd.openxmlformats-officedocument.presentationml.presentation</td>
</tr>
</tbody>
</table>
<p><span style="color: rgba(0, 128, 0, 1)">&nbsp;</span></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/sunxiaopei/p/12674973.html
頁: [1]
查看完整版本: Js React中post方式下载文件/get方式下载文件