裴开元 發表於 2021-8-16 11:35:00

【Uni-App】API笔记 P1

<h2>1、调试打印:</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">console.log()向控制台打印 log 日志

console.debug() 向控制台打印 debug 日志 注:App 端自定义组件模式下,debug 方法等同于 log 方法

console.info() 向控制台打印 info 日志

console.warn() 向控制台打印 warn 日志

console.error() 向控制台打印 error 日志</span></pre>
</div>
<ul>
<li>不同平台对于 console 方法的支持存在差异,建议在开发过程中只使用文档中提到的方法。</li>
<li>HBuilderX中有2个重要的代码块,敲<code>clog</code>:可直接输出<code>console.log()</code>;敲<code>clogv</code>:可输出<code>console.log(": " + );</code>,并且出现双光标,方便把变量名称和值同时打印出来。</li>
<li>HBuilderX 1.9.7 以上的自定义组件模式,在App端支持打印对象信息到控制台。老版本可使用<code>clogj</code>代码块将json对象转为字符串打印出来。</li>
</ul>
<p>&nbsp;</p>
<h2>2、定时器</h2>
<p>设定一个定时器。在定时到期以后执行注册的回调函数</p>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>callback</td>
<td>Function</td>
<td>是</td>
<td>回调函数</td>
</tr>
<tr>
<td>delay</td>
<td>Number</td>
<td>否</td>
<td>延迟的时间,函数的调用会在该延迟之后发生,单位 ms</td>
</tr>
<tr>
<td>rest</td>
<td>Any</td>
<td>否</td>
<td>param1, param2, ..., paramN 等附加参数,它们会作为参数传递给回调函数</td>
</tr>
</tbody>
</table>
<p>返回值</p>
<table>
<thead>
<tr><th>返回值</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>timeoutID</td>
<td>Number</td>
<td>定时器的编号,这个值可以传递给&nbsp;clearTimeout&nbsp;来取消该定时</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let stId = setTimeout(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(p1, p2, p3) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> todo ...</span>
}, 300, 'a', <span style="color: rgba(0, 0, 255, 1)">true</span>, 100)</pre>
</div>
<p>&nbsp;</p>
<p>取消由 setTimeout 设置的定时器。</p>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>timeoutID</td>
<td>Number</td>
<td>是</td>
<td>要取消的定时器的 ID</td>
</tr>
</tbody>
</table>
<div class="cnblogs_code">
<pre>clearTimeout(stId)</pre>
</div>
<p>&nbsp;</p>
<p>设定一个定时器。按照指定的周期(以毫秒计)来执行注册的回调函数</p>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>callback</td>
<td>Function</td>
<td>是</td>
<td>回调函数</td>
</tr>
<tr>
<td>delay</td>
<td>Number</td>
<td>否</td>
<td>延迟的时间,函数的调用会在该延迟之后发生,单位 ms</td>
</tr>
<tr>
<td>rest</td>
<td>Any</td>
<td>否</td>
<td>param1, param2, ..., paramN 等附加参数,它们会作为参数传递给回调函数</td>
</tr>
</tbody>
</table>
<p>返回值</p>
<table>
<thead>
<tr><th>返回值</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>intervalID</td>
<td>Number</td>
<td>定时器的编号,这个值可以传递给&nbsp;clearInterval&nbsp;来取消该定时</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>let itId = setInterval(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(p1, p2){
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> todo ...</span>
}, 1000,'aaa', <span style="color: rgba(0, 0, 255, 1)">true</span>);</pre>
</div>
<p>&nbsp;</p>
<p>取消由 setInterval 设置的定时器。</p>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>intervalID</td>
<td>Number</td>
<td>是</td>
<td>要取消的定时器的 ID</td>
</tr>
</tbody>
</table>
<div class="cnblogs_code">
<pre>clearInterval(itId);</pre>
</div>
<p>&nbsp;</p>
<h3>注意事项</h3>
<ul>
<li>App 端返回的定时器编号可能为 String 类型,使用时无需主动转换为 Number 类型</li>
</ul>
<p>&nbsp;</p>
<h2>3、ArrayBuffer &amp; Base64</h2>
<p>MDN补充扩展</p>
<div class="cnblogs_code">
<pre>https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer</span></pre>
</div>
<h3>将 Base64 字符串转成 ArrayBuffer 对象</h3>
<p>平台差异说明</p>
<table>
<thead>
<tr><th>App</th><th>H5</th><th>微信小程序</th><th>支付宝小程序</th><th>百度小程序</th><th>字节跳动小程序</th><th>快手小程序</th></tr>
</thead>
<tbody>
<tr>
<td>√</td>
<td>x</td>
<td>√</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>√</td>
</tr>
</tbody>
</table>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>base64</td>
<td>String</td>
<td>是</td>
<td>要转化成 ArrayBuffer 对象的 Base64 字符串</td>
</tr>
</tbody>
</table>
<p>示例</p>
<div class="cnblogs_code">
<pre>const base64 = 'test'<span style="color: rgba(0, 0, 0, 1)">
const arrayBuffer </span>= uni.base64ToArrayBuffer(base64)</pre>
</div>
<p>将 ArrayBuffer 对象转成 Base64 字符串</p>
<p>平台差异说明</p>
<table>
<thead>
<tr><th>App</th><th>H5</th><th>微信小程序</th><th>支付宝小程序</th><th>百度小程序</th><th>字节跳动小程序</th><th>快手小程序</th></tr>
</thead>
<tbody>
<tr>
<td>√</td>
<td>x</td>
<td>√</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>√</td>
</tr>
</tbody>
</table>
<p>参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>arrayBuffer</td>
<td>ArrayBuffer</td>
<td>是</td>
<td>要转换成 Base64 字符串的 ArrayBuffer 对象</td>
</tr>
</tbody>
</table>
<p>示例</p>
<div class="cnblogs_code">
<pre>const arrayBuffer = <span style="color: rgba(0, 0, 255, 1)">new</span> Uint8Array()
const base64 </span>= uni.arrayBufferToBase64(arrayBuffer)</pre>
</div>
<p>&nbsp;</p>
<h2><span class="token punctuation">&nbsp;4、请求 Request</span></h2>
<div class="cnblogs_code">
<pre>uni.request(object)</pre>
</div>
<p>发起网络请求。</p>
<blockquote>
<p>在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。</p>
</blockquote>
<h3>一、OBJECT 参数说明</h3>
<table>
<thead>
<tr><th>参数名</th><th>类型</th><th>必填</th><th>默认值</th><th>说明</th><th>平台差异说明</th></tr>
</thead>
<tbody>
<tr>
<td>url</td>
<td>String</td>
<td>是</td>
<td>&nbsp;</td>
<td>开发者服务器接口地址</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>data</td>
<td>Object/String/ArrayBuffer</td>
<td>否</td>
<td>&nbsp;</td>
<td>请求的参数</td>
<td>App(自定义组件编译模式)不支持ArrayBuffer类型</td>
</tr>
<tr>
<td>header</td>
<td>Object</td>
<td>否</td>
<td>&nbsp;</td>
<td>设置请求的 header,header 中不能设置 Referer。</td>
<td>App、H5端会自动带上cookie,且H5端不可手动修改</td>
</tr>
<tr>
<td>method</td>
<td>String</td>
<td>否</td>
<td>GET</td>
<td>有效值详见下方说明</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>timeout</td>
<td>Number</td>
<td>否</td>
<td>60000</td>
<td>超时时间,单位 ms</td>
<td>H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序</td>
</tr>
<tr>
<td>dataType</td>
<td>String</td>
<td>否</td>
<td>json</td>
<td>如果设为 json,会尝试对返回的数据做一次 JSON.parse</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>responseType</td>
<td>String</td>
<td>否</td>
<td>text</td>
<td>设置响应的数据类型。合法值:text、arraybuffer</td>
<td>支付宝小程序不支持</td>
</tr>
<tr>
<td>sslVerify</td>
<td>Boolean</td>
<td>否</td>
<td>true</td>
<td>验证 ssl 证书</td>
<td>仅App安卓端支持(HBuilderX 2.3.3+)</td>
</tr>
<tr>
<td>withCredentials</td>
<td>Boolean</td>
<td>否</td>
<td>false</td>
<td>跨域请求时是否携带凭证(cookies)</td>
<td>仅H5支持(HBuilderX 2.6.15+)</td>
</tr>
<tr>
<td>firstIpv4</td>
<td>Boolean</td>
<td>否</td>
<td>false</td>
<td>DNS解析时优先使用ipv4</td>
<td>仅 App-Android 支持 (HBuilderX 2.8.0+)</td>
</tr>
<tr>
<td>success</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>收到开发者服务器成功返回的回调函数</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>fail</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>接口调用失败的回调函数</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>complete</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>接口调用结束的回调函数(调用成功、失败都会执行)</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>二、请求方法有效参数值</h3>
<p>必须大写,有效值在不同平台差异说明不同。</p>
<table>
<thead>
<tr><th>method</th><th>App</th><th>H5</th><th>微信小程序</th><th>支付宝小程序</th><th>百度小程序</th><th>字节跳动小程序</th></tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>POST</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>PUT</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>DELETE</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>√</td>
<td>x</td>
</tr>
<tr>
<td>CONNECT</td>
<td>x</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<td>HEAD</td>
<td>x</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>√</td>
<td>x</td>
</tr>
<tr>
<td>OPTIONS</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>√</td>
<td>x</td>
</tr>
<tr>
<td>TRACE</td>
<td>x</td>
<td>√</td>
<td>√</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>三、success 返回参数说明</h3>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>data</td>
<td>Object/String/ArrayBuffer</td>
<td>开发者服务器返回的数据</td>
</tr>
<tr>
<td>statusCode</td>
<td>Number</td>
<td>开发者服务器返回的 HTTP 状态码</td>
</tr>
<tr>
<td>header</td>
<td>Object</td>
<td>开发者服务器返回的 HTTP Response Header</td>
</tr>
<tr>
<td>cookies</td>
<td><code>Array.&lt;string&gt;</code></td>
<td>开发者服务器返回的 cookies,格式为字符串数组</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>四、Data请求参数说明</h3>
<p>最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:</p>
<ul>
<li>对于&nbsp;<code>GET</code>&nbsp;方法,会将数据转换为 query string。例如&nbsp;<code>{ name: 'name', age: 18 }</code>&nbsp;转换后的结果是&nbsp;<code>name=name&amp;age=18</code>。</li>
<li>对于&nbsp;<code>POST</code>&nbsp;方法且&nbsp;<code>header['content-type']</code>&nbsp;为&nbsp;<code>application/json</code>&nbsp;的数据,会进行 JSON 序列化。</li>
<li>对于&nbsp;<code>POST</code>&nbsp;方法且&nbsp;<code>header['content-type']</code>&nbsp;为&nbsp;<code>application/x-www-form-urlencoded</code>&nbsp;的数据,会将数据转换为 query string。</li>
</ul>
<p>示例</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.request({
    url: </span>'https://www.example.com/request', <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)">    data: {
      text: </span>'uni.request'<span style="color: rgba(0, 0, 0, 1)">
    },
    header: {
      </span>'custom-header': 'hello' <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)">    },
    success: (res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log(res.data);
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.text = 'request success'<span style="color: rgba(0, 0, 0, 1)">;
    }
});</span></pre>
</div>
<p>&nbsp;</p>
<h3>五、返回值</h3>
<p>如果希望返回一个&nbsp;<code>requestTask</code>&nbsp;对象,需要至少传入 success / fail / complete 参数中的一个。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> requestTask =<span style="color: rgba(0, 0, 0, 1)"> uni.request({
    url: </span>'https://www.example.com/request', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实接口地址。</span>
    complete: ()=&gt;<span style="color: rgba(0, 0, 0, 1)"> {}
});
requestTask.abort();</span></pre>
</div>
<p>如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象:Promise 封装</p>
<p>&nbsp;</p>
<p>requestTask 对象的方法列表</p>
<table>
<thead>
<tr><th>方法</th><th>参数</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>abort</td>
<td>&nbsp;</td>
<td>中断请求任务</td>
</tr>
<tr>
<td>offHeadersReceived</td>
<td>&nbsp;</td>
<td>取消监听 HTTP Response Header 事件,仅<code>微信小程序平台</code>支持,文档详情</td>
</tr>
<tr>
<td>onHeadersReceived</td>
<td>&nbsp;</td>
<td>监听 HTTP Response Header 事件。会比请求完成事件更早,仅<code>微信小程序平台</code>支持,文档详情</td>
</tr>
</tbody>
</table>
<div class="cnblogs_code">
<pre>const requestTask =<span style="color: rgba(0, 0, 0, 1)"> uni.request({
    url: </span>'https://www.example.com/request', <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)">    data: {
      name: </span>'name'<span style="color: rgba(0, 0, 0, 1)">,
      age: </span>18<span style="color: rgba(0, 0, 0, 1)">
    },
    success: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res) {
      console.log(res.data);
    }
});

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 中断请求任务</span>
requestTask.abort();</pre>
</div>
<p>&nbsp;</p>
<h3>六、注意事项</h3>
<ul>
<li>请求的&nbsp;<code>header</code>&nbsp;中&nbsp;<code>content-type</code>&nbsp;默认为&nbsp;<code>application/json</code>。</li>
<li>避免在&nbsp;<code>header</code>&nbsp;中使用中文,或者使用 encodeURIComponent 进行编码,否则在百度小程序报错。(来自:快狗打车前端团队)</li>
<li>网络请求的&nbsp;<code>超时时间</code>&nbsp;可以统一在&nbsp;<code>manifest.json</code>&nbsp;中配置&nbsp;networkTimeout。</li>
<li>H5 端本地调试需注意跨域问题,参考:调试跨域问题解决方案</li>
<li>注意由于百度小程序iOS客户端,请求失败时会进入fail回调,需要针对百度增加相应的处理以解决该问题。</li>
<li>注意小程序端不支持自动保持 cookie,服务器应避免验证 cookie。如果服务器无法修改,也可以使用一些模拟手段,比如这样的工具https://github.com/charleslo1/weapp-cookie&nbsp;可以请求时带上 cookie 并将响应的 cookie 保存在本地。</li>
<li>H5端 cookie 受跨域限制(和平时开发网站时一样),旧版的 uni.request 未支持 withCredentials 配置,可以直接使用 xhr 对象或者其他类库。</li>
<li>根据 W3C 规范,H5 端无法获取 response header 中 Set-Cookie、Set-Cookie2 这2个字段,对于跨域请求,允许获取的 response header 字段只限于“simple response header”和“Access-Control-Expose-Headers”(详情)</li>
<li>uni-app 插件市场有flyio、axios等三方封装的拦截器可用</li>
<li>低版本手机自身不支持 ipv6,如果服务器仅允许 ipv6,会导致老手机无法正常运行或访问速度非常慢</li>
<li>localhost、127.0.0.1等服务器地址,只能在电脑端运行,手机端连接时不能访问。请使用标准IP并保证手机能连接电脑网络</li>
<li>debug 模式,安卓端暂时无法获取响应头,url中含有非法字符(如未编码为%20的空格)时会请求失败</li>
<li>iOS App第一次安装启动后,会弹出是否允许联网的询问框,在用户点击同意前,调用联网API会失败。请注意判断这种情况。比如官方提供的新闻模板示例(HBuilderX新建项目可选择),会判断如果无法联网,则提供一个错误页,提示用户设置网络及下拉刷新重试。</li>
<li>良好体验的App,还会判断当前是否处于飞行模式(参考)、是wifi还是3G(参考)</li>
<li>部分安卓设备,真机运行或debug模式下的网速,低于release模式很多。</li>
<li>使用一些比较小众的证书机构(如:CFCA OV OCA)签发的 ssl 证书在安卓设备请求会失败,因为这些机构的根证书不在系统内置根证书库,可以更换其他常见机构签发的证书(如:Let's Encrypt),或者配置 sslVerify 为 false 关闭 ssl 证书验证(不推荐)。</li>
<li>单次网络请求数据量建议控制在50K以下(仅指json数据,不含图片),过多数据应分页获取,以提升应用体验。</li>
</ul>
<p>&nbsp;</p>
<h2>5、拦截器</h2>
<h3>1、添加拦截器</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.addInterceptor(STRING, OBJECT)</span></pre>
</div>
<h3>STRING 参数说明</h3>
<p>需要拦截的<code>api</code>名称,如:<code>uni.addInterceptor('request', OBJECT)</code>&nbsp;,将拦截&nbsp;<code>uni.request()</code></p>
<h3>OBJECT 参数说明</h3>
<table>
<thead>
<tr><th>参数名</th><th>类型</th><th>必填</th><th>默认值</th><th>说明</th><th>平台差异说明</th></tr>
</thead>
<tbody>
<tr>
<td>invoke</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>拦截前触发</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>success</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>成功回调拦截</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>fail</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>失败回调拦截</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>complete</td>
<td>Function</td>
<td>否</td>
<td>&nbsp;</td>
<td>完成回调拦截</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.request({
    url: </span>'request/login', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实接口地址。</span>
    success: (res) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log(res.data);
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打印: {code:1,...}</span>
<span style="color: rgba(0, 0, 0, 1)">    }
});


uni.addInterceptor(</span>'request'<span style="color: rgba(0, 0, 0, 1)">, {
invoke(args) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> request 触发前拼接 url </span>
    args.url = 'https://www.example.com/'+<span style="color: rgba(0, 0, 0, 1)">args.url
},
success(args) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 请求成功后,修改code值为1</span>
    args.data.code = 1<span style="color: rgba(0, 0, 0, 1)">
},
fail(err) {
    console.log(</span>'interceptor-fail'<span style="color: rgba(0, 0, 0, 1)">,err)
},
complete(res) {
    console.log(</span>'interceptor-complete'<span style="color: rgba(0, 0, 0, 1)">,res)
}
})</span></pre>
</div>
<p>&nbsp;</p>
<h3>2、移除拦截器</h3>
<div class="cnblogs_code">
<pre>uni.removeInterceptor(STRING)</pre>
</div>
<p>STRING 参数说明</p>
<p>需要删除拦截器的<code>api</code>名称</p>
<p>&nbsp;</p>
<p>3、拦截器的适用场景</p>
<h5 id="拦截器的适用场景非常多,比如路由拦截,权限引导等。">拦截器的适用场景非常多,比如路由拦截,权限引导等。</h5>
<blockquote>
<p>你可以参考插件市场,拦截器应用示例:图片选择api时无权限,引导用户快捷打开系统设置:https://ext.dcloud.net.cn/plugin?id=5095</p>
</blockquote>
<p>&nbsp;</p>
<h2>6、文件上传 &amp;&nbsp;下载</h2>
<p>&nbsp;</p>
<h3>一、文件上传</h3>
<div class="cnblogs_code">
<pre>uni.uploadFile(OBJECT)</pre>
</div>
<p>&nbsp;</p>
<p>将本地资源上传到开发者服务器,客户端发起一个&nbsp;<code>POST</code>&nbsp;请求,其中&nbsp;<code>content-type</code>&nbsp;为&nbsp;<code>multipart/form-data</code>。</p>
<p>如页面通过&nbsp;uni.chooseImage&nbsp;等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。另外选择和上传非图像、视频文件参考:https://ask.dcloud.net.cn/article/35547。</p>
<p>&nbsp;</p>
<ul>
<li>uniCloud的上传API:https://uniapp.dcloud.io/uniCloud/storage?id=uploadfile</li>
<li>封装的更完善的uni-file-picker组件,文件选择、上传到uniCloud,一站式集成。</li>
</ul>
<p>&nbsp;</p>
<h3>OBJECT 参数说明</h3>
<table>
<thead>
<tr><th>参数名</th><th>类型</th><th>必填</th><th>说明</th><th>平台差异说明</th></tr>
</thead>
<tbody>
<tr>
<td>url</td>
<td>String</td>
<td>是</td>
<td>开发者服务器 url</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>files</td>
<td>Array</td>
<td>否</td>
<td>需要上传的文件列表。使用 files 时,filePath 和 name 不生效。</td>
<td>App、H5( 2.6.15+)</td>
</tr>
<tr>
<td>fileType</td>
<td>String</td>
<td>见平台差异说明</td>
<td>文件类型,image/video/audio</td>
<td>仅支付宝小程序,且必填。</td>
</tr>
<tr>
<td>file</td>
<td>File</td>
<td>否</td>
<td>要上传的文件对象。</td>
<td>仅H5(2.6.15+)支持</td>
</tr>
<tr>
<td>filePath</td>
<td>String</td>
<td>是</td>
<td>要上传文件资源的路径。</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>name</td>
<td>String</td>
<td>是</td>
<td>文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>header</td>
<td>Object</td>
<td>否</td>
<td>HTTP 请求 Header, header 中不能设置 Referer。</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>timeout</td>
<td>Number</td>
<td>否</td>
<td>超时时间,单位 ms</td>
<td>H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)</td>
</tr>
<tr>
<td>formData</td>
<td>Object</td>
<td>否</td>
<td>HTTP 请求中其他额外的 form data</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>success</td>
<td>Function</td>
<td>否</td>
<td>接口调用成功的回调函数</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>fail</td>
<td>Function</td>
<td>否</td>
<td>接口调用失败的回调函数</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>complete</td>
<td>Function</td>
<td>否</td>
<td>接口调用结束的回调函数(调用成功、失败都会执行)</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<p>注意:</p>
<ul>
<li>App支持多文件上传,微信小程序只支持单文件上传,传多个文件需要反复调用本API。所以跨端的写法就是循环调用本API。</li>
<li>hello uni-app中的客服反馈,支持多图上传。uni-app插件市场中也有多个封装的组件。</li>
<li>App平台选择和上传非图像、视频文件,参考https://ask.dcloud.net.cn/article/35547</li>
<li>网络请求的&nbsp;<code>超时时间</code>&nbsp;可以统一在&nbsp;<code>manifest.json</code>&nbsp;中配置&nbsp;networkTimeout。</li>
<li>支付宝小程序开发工具上传文件返回的http状态码为字符串形式,支付宝小程序真机返回的状态码为数字形式</li>
</ul>
<p>&nbsp;</p>
<h3>files参数说明</h3>
<p>files 参数是一个 file 对象的数组,file 对象的结构如下:</p>
<table>
<thead>
<tr><th>参数名</th><th>类型</th><th>必填</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>String</td>
<td>否</td>
<td>multipart 提交时,表单的项目名,默认为 file</td>
</tr>
<tr>
<td>file</td>
<td>File</td>
<td>否</td>
<td>要上传的文件对象,仅H5(2.6.15+)支持</td>
</tr>
<tr>
<td>uri</td>
<td>String</td>
<td>是</td>
<td>文件的本地地址</td>
</tr>
</tbody>
</table>
<p>Tip:</p>
<ul>
<li>如果&nbsp;<code>name</code>&nbsp;不填或填的值相同,可能导致服务端读取文件时只能读取到一个文件。</li>
</ul>
<p>&nbsp;</p>
<h3>上传成功回调函数:</h3>
<p>success 返回参数说明</p>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>data</td>
<td>String</td>
<td>开发者服务器返回的数据</td>
</tr>
<tr>
<td>statusCode</td>
<td>Number</td>
<td>开发者服务器返回的 HTTP 状态码</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.chooseImage({
    success: (chooseImageRes) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const tempFilePaths </span>=<span style="color: rgba(0, 0, 0, 1)"> chooseImageRes.tempFilePaths;
      uni.uploadFile({
            url: </span>'https://www.example.com/upload', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,非真实的接口地址</span>
            filePath: tempFilePaths,
            name: </span>'file'<span style="color: rgba(0, 0, 0, 1)">,
            formData: {
                </span>'user': 'test'<span style="color: rgba(0, 0, 0, 1)">
            },
            success: (uploadFileRes) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                console.log(uploadFileRes.data);
            }
      });
    }
});</span></pre>
</div>
<p>&nbsp;</p>
<p>返回值</p>
<p>如果希望返回一个&nbsp;<code>uploadTask</code>&nbsp;对象,需要至少传入 success / fail / complete 参数中的一个。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> uploadTask =<span style="color: rgba(0, 0, 0, 1)"> uni.uploadFile({
    url: </span>'https://www.example.com/upload', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实接口地址。</span>
    complete: ()=&gt;<span style="color: rgba(0, 0, 0, 1)"> {}
});
uploadTask.abort();</span></pre>
</div>
<p>如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象:Promise 封装</p>
<p>通过&nbsp;<code>uploadTask</code>,可监听上传进度变化事件,以及取消上传任务。</p>
<p>&nbsp;</p>
<h3>uploadTask 对象可调用的方法</h3>
<table>
<thead>
<tr><th>方法</th><th>参数</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>abort</td>
<td>&nbsp;</td>
<td>中断上传任务</td>
</tr>
<tr>
<td>onProgressUpdate</td>
<td>callback</td>
<td>监听上传进度变化</td>
</tr>
<tr>
<td>onHeadersReceived</td>
<td>callback</td>
<td>监听 HTTP Response Header 事件。会比请求完成事件更早,仅<code>微信小程序平台</code>支持,规范详情</td>
</tr>
<tr>
<td>offProgressUpdate</td>
<td>callback</td>
<td>取消监听上传进度变化事件,仅<code>微信小程序平台</code>支持,规范详情</td>
</tr>
<tr>
<td>offHeadersReceived</td>
<td>callback</td>
<td>取消监听 HTTP Response Header 事件,仅<code>微信小程序平台</code>支持,规范详情</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>onProgressUpdate&nbsp;方法 参数属性说明</h3>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>progress</td>
<td>Number</td>
<td>上传进度百分比</td>
</tr>
<tr>
<td>totalBytesSent</td>
<td>Number</td>
<td>已经上传的数据长度,单位 Bytes</td>
</tr>
<tr>
<td>totalBytesExpectedToSend</td>
<td>Number</td>
<td>预期需要上传的数据总长度,单位 Bytes</td>
</tr>
</tbody>
</table>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.chooseImage({
    success: (chooseImageRes) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const tempFilePaths </span>=<span style="color: rgba(0, 0, 0, 1)"> chooseImageRes.tempFilePaths;
      const uploadTask </span>=<span style="color: rgba(0, 0, 0, 1)"> uni.uploadFile({
            url: </span>'https://www.example.com/upload', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,非真实的接口地址</span>
            filePath: tempFilePaths,
            name: </span>'file'<span style="color: rgba(0, 0, 0, 1)">,
            formData: {
                </span>'user': 'test'<span style="color: rgba(0, 0, 0, 1)">
            },
            success: (uploadFileRes) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                console.log(uploadFileRes.data);
            }
      });

      uploadTask.onProgressUpdate((res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
            console.log(</span>'上传进度' +<span style="color: rgba(0, 0, 0, 1)"> res.progress);
            console.log(</span>'已经上传的数据长度' +<span style="color: rgba(0, 0, 0, 1)"> res.totalBytesSent);
            console.log(</span>'预期需要上传的数据总长度' +<span style="color: rgba(0, 0, 0, 1)"> res.totalBytesExpectedToSend);

            </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> (res.progress &gt; 50<span style="color: rgba(0, 0, 0, 1)">) {
                uploadTask.abort();
            }
      });
    }
});</span></pre>
</div>
<p>&nbsp;</p>
<h3>二、文件下载</h3>
<div class="cnblogs_code">
<pre>uni.downloadFile(OBJECT)</pre>
</div>
<p>下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径。</p>
<blockquote>
<p>在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。</p>
<p>在h5上是跨域的,用户需要处理好跨域问题。</p>
</blockquote>
<h3>OBJECT 参数说明</h3>
<table>
<tbody>
<tr>
<td>url</td>
<td>String</td>
<td>是</td>
<td>下载资源的 url</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>header</td>
<td>Object</td>
<td>否</td>
<td>HTTP 请求 Header, header 中不能设置 Referer。</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>timeout</td>
<td>Number</td>
<td>否</td>
<td>超时时间,单位 ms</td>
<td>H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)</td>
</tr>
<tr>
<td>success</td>
<td>Function</td>
<td>否</td>
<td>下载成功后以 tempFilePath 的形式传给页面,res = {tempFilePath: '文件的临时路径'}</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>fail</td>
<td>Function</td>
<td>否</td>
<td>接口调用失败的回调函数</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>complete</td>
<td>Function</td>
<td>否</td>
<td>接口调用结束的回调函数(调用成功、失败都会执行)</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>注:文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用&nbsp;uni.saveFile,才能在应用下次启动时访问得到。</p>
<p>&nbsp;</p>
<h3>success 返回参数说明</h3>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>tempFilePath</td>
<td>String</td>
<td>临时文件路径,下载后的文件会存储到一个临时文件</td>
</tr>
<tr>
<td>statusCode</td>
<td>Number</td>
<td>开发者服务器返回的 HTTP 状态码</td>
</tr>
</tbody>
</table>
<p>注意</p>
<ul>
<li>网络请求的&nbsp;<code>超时时间</code>&nbsp;可以统一在&nbsp;<code>manifest.json</code>&nbsp;中配置&nbsp;networkTimeout。</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">uni.downloadFile({
    url: </span>'https://www.example.com/file/test', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实的资源</span>
    success: (res) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.statusCode === 200<span style="color: rgba(0, 0, 0, 1)">) {
            console.log(</span>'下载成功'<span style="color: rgba(0, 0, 0, 1)">);
      }
    }
});</span></pre>
</div>
<h3>返回值</h3>
<p>如果希望返回一个&nbsp;<code>downloadTask</code>&nbsp;对象,需要至少传入 success / fail / complete 参数中的一个。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> downloadTask =<span style="color: rgba(0, 0, 0, 1)"> uni.downloadFile({
    url: </span>'https://www.example.com/file/test', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实接口地址。</span>
    complete: ()=&gt;<span style="color: rgba(0, 0, 0, 1)"> {}
});
downloadTask.abort();</span></pre>
</div>
<p>如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象:Promise 封装</p>
<p>通过&nbsp;<code>downloadTask</code>,可监听下载进度变化事件,以及取消下载任务。</p>
<h3>downloadTask 对象可执行的方法</h3>
<table>
<thead>
<tr><th>方法</th><th>参数</th><th>说明</th><th>最低版本</th></tr>
</thead>
<tbody>
<tr>
<td>abort</td>
<td>&nbsp;</td>
<td>中断下载任务</td>
<td>*</td>
</tr>
<tr>
<td>onProgressUpdate</td>
<td>callback</td>
<td>监听下载进度变化</td>
<td>*</td>
</tr>
<tr>
<td>onHeadersReceived</td>
<td>callback</td>
<td>监听 HTTP Response Header 事件,会比请求完成事件更早,仅<code>微信小程序平台</code>支持,规范详情</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>offProgressUpdate</td>
<td>callback</td>
<td>取消监听下载进度变化事件,仅<code>微信小程序平台</code>支持,规范详情</td>
</tr>
<tr>
<td>offHeadersReceived</td>
<td>callback</td>
<td>取消监听 HTTP Response Header 事件,仅<code>微信小程序平台</code>支持,规范详情</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>onProgressUpdate 返参属性说明</h3>
<table>
<thead>
<tr><th>参数</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>progress</td>
<td>Number</td>
<td>下载进度百分比</td>
</tr>
<tr>
<td>totalBytesWritten</td>
<td>Number</td>
<td>已经下载的数据长度,单位 Bytes</td>
</tr>
<tr>
<td>totalBytesExpectedToWrite</td>
<td>Number</td>
<td>预期需要下载的数据总长度,单位 Bytes</td>
</tr>
</tbody>
</table>
<div class="cnblogs_code">
<pre>const downloadTask =<span style="color: rgba(0, 0, 0, 1)"> uni.downloadFile({
    url: </span>'http://www.example.com/file/test', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">仅为示例,并非真实的资源</span>
    success: (res) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.statusCode === 200<span style="color: rgba(0, 0, 0, 1)">) {
            console.log(</span>'下载成功'<span style="color: rgba(0, 0, 0, 1)">);
      }
    }
});

downloadTask.onProgressUpdate((res) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log(</span>'下载进度' +<span style="color: rgba(0, 0, 0, 1)"> res.progress);
    console.log(</span>'已经下载的数据长度' +<span style="color: rgba(0, 0, 0, 1)"> res.totalBytesWritten);
    console.log(</span>'预期需要下载的数据总长度' +<span style="color: rgba(0, 0, 0, 1)"> res.totalBytesExpectedToWrite);

    </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> (res.progress &gt; 50<span style="color: rgba(0, 0, 0, 1)">) {
      downloadTask.abort();
    }
});</span></pre>
</div>
<p>&nbsp;</p>
<h2>7、WebSocket &amp; SocketTask</h2>
<p>一般来说不涉及,见官方文档</p>
<div class="cnblogs_code">
<pre>https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">uniapp.dcloud.io/api/request/websocket<br>https://uniapp.dcloud.io/api/request/socket-task<br></span></pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/mindzone/p/15146349.html
頁: [1]
查看完整版本: 【Uni-App】API笔记 P1