风流唐伯虎 發表於 2020-6-20 18:47:00

JavaScript中的Fetch函数

<h1 style="text-align: center"><span style="font-size: 16px">JavaScript中的Fetch函数</span></h1>
<p>Fetch API提供了一个JavaScript接口,用于访问和操作Http管道的一些具体的部分,例如请求和响应。还提供一个fetch()方法,该方法提供一种简单,合理的方式来跨网络异步获取资源。</p>
<p>这种功能以前是使用XMLHttpRequest实现的。Fetch挺了一个更理想的替代方案,可以很容易的被其他技术使用。例如Service Workers。Fetch还提供了专门的逻辑空间来定义其他与Http相关的概念,例如Cors和http扩展。</p>
<p>&nbsp;</p>
<p>注意:fetch规范与Jquery.ajax()主要有三种方式不同:</p>
<p>1.当接收到一个代表错误的Http状态码时,从fetch()返回的Promise不会被标记为reject,即使响应的http状态码时404或500.它将Promise状态标记为resolve,但是会将resolve的返回值ok属性设置为false。仅当网络故障时或者请求被阻止时,才会标记为reject。</p>
<p>2.fetch()不会接受跨域的cookies,也不能使用fetch建立跨域会话,其他网站的set-cookies头部字段将会被无视。</p>
<p>年tch不会发送cookies,除非使用了credentials的初始化选项。2017年8月25日后,默认的credentials政策更改为same-origin。fixfox在61.0b134版本进行了修改。</p>
<p>示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">fetch(url)
.then(</span><span style="color: rgba(0, 0, 255, 1)">function</span>(response){<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> response.json()})
.then(</span><span style="color: rgba(0, 0, 255, 1)">function</span>(myJson){console.log(myJson)})</pre>
</div>
<p>示例中通过网络获取一个json文件并将其打印到控制台。</p>
<p>最简单的用法只提供一个茶杯上个月用来指明fetch到的资源路径,然后返回一个包含响应结果的promise(一个Response对象)。</p>
<p>它只是一个Http响应并不是真的JSON,为了获取JSON的内容,还需要使用json()方法,在Body的mixin中定义,被Request和Response对象实现。</p>
<p>&nbsp;</p>
<p>带两个参数的示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Example POST method implementation:</span>
<span style="color: rgba(0, 0, 0, 1)">
postData(</span>'http://example.com/answer', {answer: 42<span style="color: rgba(0, 0, 0, 1)">})
.then(data </span>=&gt; console.log(data)) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> JSON from `response.json()` call</span>
.<span style="color: rgba(0, 0, 255, 1)">catch</span>(error =&gt;<span style="color: rgba(0, 0, 0, 1)"> console.error(error))

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> postData(url, data) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Default options are marked with *</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> fetch(url, {
    body: JSON.stringify(data), </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> must match 'Content-Type' header</span>
    cache: 'no-cache', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> *default, no-cache, reload, force-cache, only-if-cached</span>
    credentials: 'same-origin', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> include, same-origin, *omit</span>
<span style="color: rgba(0, 0, 0, 1)">    headers: {
      </span>'user-agent': 'Mozilla/4.0 MDN Example'<span style="color: rgba(0, 0, 0, 1)">,
      </span>'content-type': 'application/json'<span style="color: rgba(0, 0, 0, 1)">
    },
    method: </span>'POST', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> *GET, POST, PUT, DELETE, etc.</span>
    mode: 'cors', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> no-cors, cors, *same-origin</span>
    redirect: 'follow', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> manual, *follow, error</span>
    referrer: 'no-referrer', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> *client, no-referrer</span>
<span style="color: rgba(0, 0, 0, 1)">})
.then(response </span>=&gt; response.json()) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> parses response to JSON</span>
}</pre>
</div>
<p>发送带凭证的请求:</p>
<div class="cnblogs_code">
<pre>fetch('https://example.com'<span style="color: rgba(0, 0, 0, 1)">, {
credentials: </span>'include'<span style="color: rgba(0, 0, 0, 1)">
})</span></pre>
</div>
<p>如果只想在请求URL与调用脚本位于同一起源处时发送凭证,添加credentials:'same-origin'</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> The calling script is on the origin 'https://example.com'</span>
<span style="color: rgba(0, 0, 0, 1)">
fetch(</span>'https://example.com'<span style="color: rgba(0, 0, 0, 1)">, {
credentials: </span>'same-origin'<span style="color: rgba(0, 0, 0, 1)">
})</span></pre>
</div>
<p>为确保浏览器不在请求中包含凭证,使用omit</p>
<div class="cnblogs_code">
<pre>fetch('https://example.com'<span style="color: rgba(0, 0, 0, 1)">, {
credentials: </span>'omit'<span style="color: rgba(0, 0, 0, 1)">
})</span></pre>
</div>
<p>上传JSON数据示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> url = 'https://example.com/profile'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data = {username: 'example'<span style="color: rgba(0, 0, 0, 1)">};

fetch(url, {
method: </span>'POST', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> or 'PUT'</span>
body: JSON.stringify(data), <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> data can be `string` or {object}!</span>
headers: <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Headers({
    </span>'Content-Type': 'application/json'<span style="color: rgba(0, 0, 0, 1)">
})
}).then(res </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> res.json())
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(error =&gt; console.error('Error:'<span style="color: rgba(0, 0, 0, 1)">, error))
.then(response </span>=&gt; console.log('Success:', response));</pre>
</div>
<p>上传文件示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> formData = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FormData();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fileField = document.querySelector("input"<span style="color: rgba(0, 0, 0, 1)">);

formData.append(</span>'username', 'abc123'<span style="color: rgba(0, 0, 0, 1)">);
formData.append(</span>'avatar', fileField.files);

fetch(</span>'https://example.com/profile/avatar'<span style="color: rgba(0, 0, 0, 1)">, {
method: </span>'PUT'<span style="color: rgba(0, 0, 0, 1)">,
body: formData
})
.then(response </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> response.json())
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(error =&gt; console.error('Error:'<span style="color: rgba(0, 0, 0, 1)">, error))
.then(response </span>=&gt; console.log('Success:', response));</pre>
</div>
<p>上传多个文件示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> formData = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FormData();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> photos = document.querySelector("input"<span style="color: rgba(0, 0, 0, 1)">);

formData.append(</span>'title', 'My Vegas Vacation'<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)"> formData 只接受文件、Blob 或字符串,不能直接传递数组,所以必须循环嵌入</span>
<span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i &lt; photos.files.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
    formData.append(</span>'photo'<span style="color: rgba(0, 0, 0, 1)">, photos.files);
}

fetch(</span>'https://example.com/posts'<span style="color: rgba(0, 0, 0, 1)">, {
method: </span>'POST'<span style="color: rgba(0, 0, 0, 1)">,
body: formData
})
.then(response </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> response.json())
.then(response </span>=&gt; console.log('Success:'<span style="color: rgba(0, 0, 0, 1)">, JSON.stringify(response)))
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(error =&gt; console.error('Error:', error));</pre>
</div>
<p>检测请求是否成功:</p>
<p>如果网络故障,fetch()promise将会reject戴上一个TypeError对象,虽然这种情况经常遇到权限问题或者是类似问题,如404不是一个网络故障。想精确的判断fetch是否成功,需要promise resolved的情况,此时再判断Response.ok是不是true。</p>
<div class="cnblogs_code">
<pre>fetch('flowers.jpg').then(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(response) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(response.ok) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> response.blob();
}
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Error('Network response was not ok.'<span style="color: rgba(0, 0, 0, 1)">);
}).then(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(myBlob) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> objectURL =<span style="color: rgba(0, 0, 0, 1)"> URL.createObjectURL(myBlob);
myImage.src </span>=<span style="color: rgba(0, 0, 0, 1)"> objectURL;
}).</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(error) {
console.log(</span>'There has been a problem with your fetch operation: '<span style="color: rgba(0, 0, 0, 1)">, error.message);
});</span></pre>
</div>
<p>自定义请求对象:</p>
<p>除了传给fetch一个资源的地址,还可以通过Request来构造函数来创建一个request对象,然后再传给fetch。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> myHeaders = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Headers();

</span><span style="color: rgba(0, 0, 255, 1)">var</span> myInit = { method: 'GET'<span style="color: rgba(0, 0, 0, 1)">,
               headers: myHeaders,
               mode: </span>'cors'<span style="color: rgba(0, 0, 0, 1)">,
               cache: </span>'default'<span style="color: rgba(0, 0, 0, 1)"> };

</span><span style="color: rgba(0, 0, 255, 1)">var</span> myRequest = <span style="color: rgba(0, 0, 255, 1)">new</span> Request('flowers.jpg'<span style="color: rgba(0, 0, 0, 1)">, myInit);

fetch(myRequest).then(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(response) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> response.blob();
}).then(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(myBlob) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> objectURL =<span style="color: rgba(0, 0, 0, 1)"> URL.createObjectURL(myBlob);
myImage</span></pre>
</div>
<p><code>Request()</code>&nbsp;和&nbsp;<code>fetch()</code>&nbsp;接受同样的参数。你甚至可以传入一个已存在的 request 对象来创造一个拷贝:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> anotherRequest = <span style="color: rgba(0, 0, 255, 1)">new</span> Request(myRequest,myInit);</pre>
</div>
<p>Headers示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> content = "Hello World"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> myHeaders = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Headers();
myHeaders.append(</span>"Content-Type", "text/plain"<span style="color: rgba(0, 0, 0, 1)">);
myHeaders.append(</span>"Content-Length"<span style="color: rgba(0, 0, 0, 1)">, content.length.toString());
myHeaders.append(</span>"X-Custom-Header", "ProcessThisImmediately");</pre>
</div>
<p>多维数组或者对象字面量:</p>
<div class="cnblogs_code">
<pre>myHeaders = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Headers({
</span>"Content-Type": "text/plain"<span style="color: rgba(0, 0, 0, 1)">,
</span>"Content-Length"<span style="color: rgba(0, 0, 0, 1)">: content.length.toString(),
</span>"X-Custom-Header": "ProcessThisImmediately"<span style="color: rgba(0, 0, 0, 1)">,
});</span></pre>
</div>
<p>它的内容可以被获取:</p>
<div class="cnblogs_code">
<pre>console.log(myHeaders.has("Content-Type")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(myHeaders.has("Set-Cookie")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span>
myHeaders.set("Content-Type", "text/html"<span style="color: rgba(0, 0, 0, 1)">);
myHeaders.append(</span>"X-Custom-Header", "AnotherValue"<span style="color: rgba(0, 0, 0, 1)">);

console.log(myHeaders.get(</span>"Content-Length")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 11</span>
console.log(myHeaders.getAll("X-Custom-Header")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ["ProcessThisImmediately", "AnotherValue"]</span>
<span style="color: rgba(0, 0, 0, 1)">
myHeaders.</span><span style="color: rgba(0, 0, 255, 1)">delete</span>("X-Custom-Header"<span style="color: rgba(0, 0, 0, 1)">);
console.log(myHeaders.getAll(</span>"X-Custom-Header")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> [ ]</span></pre>
</div>
<p>虽然一些操作只能在&nbsp;<code>ServiceWorkers</code>&nbsp;中使用,但是它提供了更方便的操作 Headers 的 API。</p>
<p>如果使用了一个不合法的HTTP Header属性名,那么Headers的方法通常都抛出 TypeError 异常。如果不小心写入了一个不可写的属性,也会抛出一个 TypeError 异常。除此以外的情况,失败了并不抛出异常。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> myResponse =<span style="color: rgba(0, 0, 0, 1)"> Response.error();
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
myResponse.headers.set(</span>"Origin", "http://mybank.com"<span style="color: rgba(0, 0, 0, 1)">);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)">(e) {
console.log(</span>"Cannot pretend to be a bank!"<span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p>最好在在使用之前检查内容类型&nbsp;<code>content-type</code>&nbsp;是否正确,比如:</p>
<div class="cnblogs_code">
<pre>fetch(myRequest).then(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(response) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(response.headers.get("content-type") === "application/json"<span style="color: rgba(0, 0, 0, 1)">) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> response.json().then(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(json) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> process your JSON further</span>
<span style="color: rgba(0, 0, 0, 1)">    });
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
    console.log(</span>"Oops, we haven't got JSON!"<span style="color: rgba(0, 0, 0, 1)">);
}
});</span></pre>
</div>
<h3 id="Guard">Guard</h3>
<p>由于 Headers 可以在 request 请求中被发送或者在 response 请求中被接收,并且规定了哪些参数是可写的,Headers 对象有一个特殊的 guard 属性。这个属性没有暴露给 Web,但是它影响到哪些内容可以在 Headers 对象中被操作。</p>
<p>可能的值如下:</p>
<ul>
<li><code>none</code>:默认的</li>
<li><code>request</code>:从 request 中获得的 headers(<code>Request.headers</code>)只读</li>
<li><code>request-no-cors</code>:从不同域(<code>Request.mode</code>&nbsp;<code>no-cors</code>)的 request 中获得的 headers 只读</li>
<li><code>response</code>:从 response 中获得的 headers(<code>Response.headers</code>)只读</li>
<li><code>immutable</code>:在 ServiceWorkers 中最常用的,所有的 headers 都只读。</li>
</ul>
<h2 id="Response_对象">Response 对象</h2>
<p>如上所述,<code>Response</code>&nbsp;实例是在&nbsp;<code>fetch()</code>&nbsp;处理完 promise 之后返回的。</p>
<p>你会用到的最常见的 response 属性有:</p>
<ul>
<li><code>Response.status</code>&nbsp;— 整数(默认值为200)为response的状态码。</li>
<li><code>Response.statusText</code>&nbsp;— 字符串(默认值为"OK"),该值与 HTTP 状态码消息对应。</li>
<li><code>Response.ok</code>&nbsp;— 如上所示,该属性是来检查response的状态是否在 200 - 299(包括200 和 299)这个范围内。该属性返回一个<code>布尔值</code>。</li>
</ul>
<p>它的实例也可用通过 JavaScript 来创建,但只有在&nbsp;<code>ServiceWorkers</code>&nbsp;中才真正有用,当使用&nbsp;<code>respondWith()</code>&nbsp;方法并提供了一个自定义的 response 来接受 request 时:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> myBody = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Blob();

addEventListener(</span>'fetch', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(event) {
event.respondWith(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Response(myBody, {
    headers: { </span>"Content-Type" : "text/plain"<span style="color: rgba(0, 0, 0, 1)"> }
});
});</span></pre>
</div>
<p><code>Response()</code>&nbsp;构造方法接受两个可选参数—— response 的数据体和一个初始化对象(与<code>Request()</code>&nbsp;所接受的 init 参数类似。)</p>
<h2 id="Body">Body</h2>
<p>不管是请求还是响应都能够包含 body 对象。body 也可以是以下任意类型的实例。</p>
<ul>
<li><code>ArrayBuffer</code></li>
<li><code>ArrayBufferView</code>&nbsp;(Uint8Array等)</li>
<li><code>Blob</code>/File</li>
<li>string</li>
<li><code>URLSearchParams</code></li>
<li><code>FormData</code></li>
</ul>
<p><code>Body</code>&nbsp;类定义了以下方法(这些方法都被&nbsp;<code>Request</code>&nbsp;和<code>Response</code>所实现)以获取 body 内容。这些方法都会返回一个被解析后的<code>Promise</code>对象和数据。</p>
<ul>
<li><code>arrayBuffer()</code></li>
<li><code>blob()</code></li>
<li><code>json()</code></li>
<li><code>text()</code></li>
<li><code>formData()</code></li>
</ul>
<p>比起XHR来,这些方法让非文本化的数据使用起来更加简单。</p>
<p>请求体可以由传入 body 参数来进行设置:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> form = <span style="color: rgba(0, 0, 255, 1)">new</span> FormData(document.getElementById('login-form'<span style="color: rgba(0, 0, 0, 1)">));
fetch(</span>"/login"<span style="color: rgba(0, 0, 0, 1)">, {
method: </span>"POST"<span style="color: rgba(0, 0, 0, 1)">,
body: form
})</span></pre>
</div>
<h2 id="特性检测">特性检测</h2>
<p>Fetch API 的支持情况,可以通过检测<code>Headers</code>,&nbsp;<code>Request</code>,&nbsp;<code>Response</code>&nbsp;或&nbsp;<code>fetch()</code>是否在<code>Window</code>&nbsp;或&nbsp;<code>Worker</code>&nbsp;域中。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(self.fetch) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> run my fetch request here</span>
} <span style="color: rgba(0, 0, 255, 1)">else</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)"> do something with XMLHttpRequest?</span>
}</pre>
</div>
<h2 id="Polyfill">Polyfill</h2>
<p>如果要在不支持的浏览器中使用 Fetch,可以使用&nbsp;Fetch Polyfill。</p><br><br>
来源:https://www.cnblogs.com/baron-li/p/13170001.html
頁: [1]
查看完整版本: JavaScript中的Fetch函数