AJAX—一种异步网络请求技术(XMLHttpRequest、jQuery、Axios、Fetch)
AJAX 即 Asynchronous JavaScript and XML,是一种创建交互式网页应用的网页开发技术。该技术 2005 年由 Jesse James Garrett 提出,AJAX 不是新的编程语言,而是对现有技术(XMLHttpRequest(核心)、HTML,JS,CSS,DOM,XML,XSLT等)的整合。值得注意的是,尽管 X 在 AJAX 中代表 XML,但由于 JSON 的诸多优势,目前 JSON 的使用比 XML 更加普遍。
HTTP
AJAX 实际上是发起了一次 HTTP 请求,在学习 AJAX 前需要了解 HTTP 报文相关知识。
请求报文格式
客户端发送一个 HTTP 请求到服务器。请求消息包括:请求行(request line)、请求头(header)、空行和请求体(body)四个部分组成。
请求行: POST/ /s?ie=utf-8 HTTP/1.1
请求头: Host: blog.quietguoguo.com
Referer: https://blog.quietguoguo.com/4170.html
Accept: text/html,application/xhtml+xml...
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64)...
Cookie: T=1614678821:RT=1614678821...
...
空行
请求体: user_id=admin&password=123...
HTTP 请求包含 8 种类型,实际应用中常用的也就是 GET 和 POST 。
GET:向特定的资源发出请求。
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改。
OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送'*'的请求来测试服务器的功能性。
HEAD:向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
PUT:向指定资源位置上传其最新内容。
DELETE:请求服务器删除 Request-URI 所标识的资源。
TRACE:回显服务器收到的请求,主要用于测试或诊断。
CONNECT:HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
响应报文格式
服务器返回一个响应消息给客户端。响应消息包括:响应行(request line)、响应头(header)、空行和响应体(body)四个部分组成。
响应行: HTTP/1.1 200 OK
响应头: Content-Type: text/html;charset=utf-8
Content-Encoding: gzip
Set-Cookie: BDSVRTM=14; path=/
Date: Sun, 28 Mar 2021 12:14:47 GMT
Transfer-Encoding: chunked
...
空行
响应体: <html>
<head></head>
<body></body>
</html>
响应状态码包含:1**-信息;2**-成功;3**-重定向;4**-客户端错误;5**-服务器错误,详细状态码如下:
100 Continue:继续。客户端应继续其请求
101 Switching Protocols:切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK:请求成功。一般用于GET与POST请求
201 Created:已创建。成功请求并创建了新的资源
202 Accepted:已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information:非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content:无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content:重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content:部分内容。服务器成功处理了部分GET请求
301 Moved Permanently:永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found:临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
304 Not Modified:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy:使用代理。所请求的资源必须通过代理访问
306 Unused:已经被废弃的HTTP状态码
307 Temporary Redirect:临时重定向。与302类似。使用GET请求重定向
400 Bad Request:客户端请求的语法错误,服务器无法理解
401 Unauthorized:请求要求用户的身份认证
402 Payment Required:保留,将来使用
403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found:服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed:客户端请求中的方法被禁止
406 Not Acceptable:服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required:请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out:服务器等待客户端发送的请求时间过长,超时
409 Conflict:服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone:客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required:服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed:客户端请求信息的先决条件错误
413 Request Entity Too Large:由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large:请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type:服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable:客户端请求的范围无效
417 Expectation Failed:服务器无法满足Expect的请求头信息
500 Internal Server Error:服务器内部错误,无法完成请求
501 Not Implemented:服务器不支持请求的功能,无法完成请求
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable:由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out:充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported:服务器不支持请求的HTTP协议的版本,无法完成处理
XMLHttpRequest(原生 AJAX)
作为 AJAX 技术的核心,XMLHttpRequest 构造函数并不仅限于 XML 文档。它之所以使用 XML 开头是因为在它诞生之时,原先用于异步数据交换的主要格式便是 XML 。XMLHttpRequest 是一个对象,在使用前我们需要通过 new 将其实例化。
let xhr = new XMLHttpRequest();
XMLHttpRequest 常用属性包括:
readyState:只读,返回请求的状态码
0:尚未初始化
1:open 方法调用完毕
2:send 方法调用完毕
3:服务端返回了部分结果
4:服务端返回了所有结果
status:只读,返回请求的响应状态码
statusText:只读,返回完整的请求的响应状态文本,如:200 OK
timeout:设置请求的最大请求时间,超时自动终止
responseType:用于定义响应类型
responseURL:只读,返回经序列号的响应 URL
response:只读,基于 responseType 返回一下响应实体
responseText:只读,返回请求的响应,未成功或尚未发送则返回 null
responseXML:只读,返回一个 Document,未成功或未发送或无法解析时返回 null
XMLHttpRequest 常用方法包括:
open():初始化请求,仅 JS 代码中使用
xhr.open(method, url, async, user, password);
send():发送请求,默认为异步请求
xhr.send(body)
abort():中止已发出的请求
xhr.abort();
setRequestHeader():设置 HTTP 的请求头,必须在 open() 之后 send() 之前使用
xhr.setRequestHeader(header, value);
getAllResponseHeaders():返回所有 CRLF 分割的响应头,未收到响应则返回 null
var headers = xhr.getAllResponseHeaders();
getResponseHeader():返回包含指定响应头的字符串,未收到响应或响应头不存在则返回 null
var myHeader = xhr.getResponseHeader(name)
overrideMineType():覆写由服务器返回的 MIME 类型
xhr.overrideMimeType(mimeType)
XMLHttpRequest 常用事件包括:
onreadystatechange:当 readyState 变化时触发
abort:同 onabort,当请求停止时触发
error:同 onerror,当请求错误时触发
load:同 onload,当请求成功时触发
loadstart:同 onloadstart,当请求接收到响应数据时触发
loadend:同 onloadend,当请求结束时触发
progress:同 onprogress,当请求接收到更多数据时,周期性地触发
timeout:同 ontimeout,当请求超时时触发
示例代码:
const btn = document.getElementsByTagName('button')[0];
let textarea = document.getElementsByTagName('textarea')[0];
let isSending = false;
let xhr = null;
btn.onclick = function(){
if (isSending) xhr.abort(); // 终止请求
xhr = new XMLHttpRequest(); // 实例化 XMLHttpRequest
isSending = true;
xhr.timeout = 3000; // 设置超时时间
xhr.open('POST', 'http://127.0.0.1:3000/server'); // 初始化请求
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 设置请求头
xhr.send('user=admin&password=1234567'); // 发送请求
xhr.onreadystatechange = function(){
if( xhr.readyState = 4 ){
isSending = false;
if( xhr.status >= 200 && xhr.status < 300 ){
console.log('response:' + xhr.response)
console.log('responseText:' + xhr.responseText)
console.log('responseXML:' + xhr.responseXML)
console.log('status:' + xhr.status)
console.log('statusText:' + xhr.statusText)
console.log('getAllResponseHeader:' + xhr.getAllResponseHeaders())
console.log('getResponseHeader:' + xhr.getResponseHeader('Content-Type'))
textarea.innerHTML = xhr.response
}
}
}
}
jQuery 发送 AJAX
jQuery 中可用于发送 AJAX 的方法包括
$.get() 方法发起 AJAX 请求
$.get() 方法使用 HTTP GET 请求从服务器加载数据。
$(selector).get(url, data, function(response,status,xhr), dataType)
data:可选,请求中附带的数据
function(response, status, xhr):可选,请求成功时运行的处理函数
response:请求的结果数据
status:请求的状态("success"、"notmodified"、"error"、"timeout"、"parsererror")
xhr:XMLHttpRequest 对象
dataType:可选,预期的服务器响应的数据类型。不设置则 jQuery 会智能判断,可能的类型有:
xml:一个 XML 文档
html:HTML 作为纯文本
text:纯文本字符串
script:以 JavaScript 运行响应,并以纯文本返回
json:以 JSON 运行响应,并以 JavaScript 对象返回
jsonp:使用 JSONP 加载一个 JSON 块,将添加一个 "?callback=?" 到 URL 来规定回调
示例
// GET
$('button').eq(0).on('click', function(){
$.get(
'http://127.0.0.1:3000/server',
{a: 100, b: 200},
function(data){
console.log(data)
$('.ajax-result').html(data)
}
)
})
$.post() 方法发起 AJAX 请求
$.post() 方法使用 HTTP POST 请求从服务器加载数据。
$(selector).post(url, data, function(response,status,xhr), dataType)
data:可选,请求中附带的数据
function(response, status, xhr):可选,请求成功时运行的处理函数
response:请求的结果数据
status:请求的状态("success"、"notmodified"、"error"、"timeout"、"parsererror")
xhr:XMLHttpRequest 对象
dataType:可选,预期的服务器响应的数据类型。不设置则 jQuery 会智能判断,可能的类型有:
xml:一个 XML 文档
html:HTML 作为纯文本
text:纯文本字符串
script:以 JavaScript 运行响应,并以纯文本返回
json:以 JSON 运行响应,并以 JavaScript 对象返回
jsonp:使用 JSONP 加载一个 JSON 块,将添加一个 "?callback=?" 到 URL 来规定回调
示例
// POST
$('button').eq(1).on('click', function(){
$.post(
'http://127.0.0.1:3000/server',
{a: 100, b: 200},
function(data){
console.log(data)
$('.ajax-result').html(data)
}
)
})
$.load() 方法发起 AJAX 请求
$.load() 方法从服务器加载数据,并把返回的数据放置到指定的元素中。
$(selector).load(url, data, function(response,status,xhr))
data:可选,请求中附带的数据
function(response, status, xhr):可选,请求成功时运行的处理函数
response:请求的结果数据
status:请求的状态("success"、"notmodified"、"error"、"timeout"、"parsererror")
xhr:XMLHttpRequest 对象
示例
// LOAD txt 文件中 id 为 p2 的 <p> 标签内容
$('button').eq(2).on('click', function(){
$('#ajax-text').load(
'http://127.0.0.1:3000/server/file-ajax-text.txt #p2'
)
})
$.ajax() 方法发起 AJAX 请求
所有的 jQuery AJAX 方法都源于 ajax() 方法,该方法通常用于其他方法不能完成的请求。
$.ajax({name:value, name:value, ... })
url:规定发送请求的 URL。默认是当前页面
type:规定请求的类型(GET 或 POST)
data:规定要发送到服务器的数据
timeout:设置本地的请求超时时间(以毫秒计)
dataType:预期的服务器响应的数据类型
async:布尔值,表示请求是否异步处理。默认是 true
cache:布尔值,表示浏览器是否缓存被请求页面。默认是 true
contentType:发送数据到服务器时所使用的内容类型。默认是 "application/x-www-form-urlencoded"
success(result,status,xhr):当请求成功时运行的函数
error(xhr,status,error):如果请求失败要运行的函数
complete(xhr,status):请求完成时运行的函数(在 success 和 error 函数之后)
context:为所有 AJAX 相关的回调函数规定 "this" 值
beforeSend(xhr):发送请求前运行的函数
dataFilter(data,type):用于处理 XMLHttpRequest 原始响应数据的函数
processData:布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true
traditional:布尔值,规定是否使用参数序列化的传统样式
global:布尔值,规定是否为请求触发全局 AJAX 事件处理程序。默认是 true
ifModified:布尔值,规定是否仅在最后一次请求以来响应发生改变时才请求成功。默认是 false
jsonp:在一个 jsonp 中重写回调函数的字符串
jsonpCallback:在一个 jsonp 中规定回调函数的名称
username:规定在 HTTP 访问认证请求中使用的用户名
password:规定在 HTTP 访问认证请求中使用的密码
scriptCharset:规定请求的字符集
xhr:用于创建 XMLHttpRequest 对象的函数
示例
// AJAX
$('button').eq(3).on('click', function(){
$.ajax({
url: 'http://127.0.0.1:3000/server',
type: 'POST',
data: {user: "Admin", password: "123456"},
timeout: 5000,
success: function(result, status, xhr){
console.log('result:' + result)
console.log('status:' + status)
console.log('xhr:')
console.log(xhr)
$('.ajax-result').html(result)
},
error: function(xhr, status, error){
console.log('xhr:')
console.log(xhr)
console.log('status:'+status)
console.log('error:' + error)
}
})
})
更多内容访问:jQuery API
Axios 发送 AJAX
Axios 是一个基于 Promise 的 HTTP 库,本质上也是对原生 XHR 的封装,只不过它是 Promise 的实现版本,符合最新的ES规范。另外,它还是 React 与 Vue 推荐使用的异步请求工具包。Axios 为所有请求提供了别名:
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios.request() 方法发送 AJAX请求
axios.request(config) 创建一个 XMLHttpRequest 对象
axios.request(config)
config 是一个对象,里面包裹 axios.request 中的各种配置。
axios.get() 方法发起 AJAX 请求
axios.get() 是 axios 快捷发起 get 请求的一个方法。
axios.get(url[, config])
config:请求的配置项
axios.post() 方法发起 AJAX 请求
axios.get() 是 axios 快捷发起 post 请求的一个方法。
axios.post(url[, data[, config]])
config:请求的配置项
axios() 方法发起 AJAX 请求
axios(config)
config 是一个对象,里面包裹 axios 中的各种配置,上面 get 及 post 方法也应用此配置。主要配置包括:
url:请求的服务器 URL
method:请求时使用的方法,默认 get
headers:自定义请求头,默认的请求头修改了也无效,具体看源码
params:与请求一起发送的 URL 参数
timeout:指定请求超时的毫秒数(0 表示无超时时间)
responseType:服务器响应的数据类型
responseEncoding:服务器响应的数据编码格式
baseURL:基准 url ,自动加在 url 前面,除非 url 是一个绝对 URL
transformRequest:在向服务器发送前,修改请求数据
transformResponse:在传递给 then/catch 前,允许修改响应数据
paramsSerializer:用于 params 序列化的函数
data:作为请求主体被发送的数据,只适用于 PUT, POST, 和 PATCH
withCredentials:跨域请求时是否需要使用凭证,默认 false
adapter:许自定义处理请求,以使测试更轻松
auth:使用 HTTP 基础验证,并提供凭据
xsrfCookieName:用作 xsrf token 传输中的 cookie 名称
xsrfHeaderName:用作 xsrf token 传输中的 header 名称
onUploadProgress:允许为上传处理进度事件
onDownloadProgress:允许为下载处理进度事件
maxContentLength:定义允许的响应内容的最大尺寸
maxRedirects:定义在 node.js 中 follow 的最大重定向数目
socketPath:定义 node.js 中用于 UNIX Socket 的路径
httpAgent:在 node.js 中用于定义在执行 http 时使用的自定义代理
httpsAgent:在 node.js 中用于定义在执行 https 时使用的自定义代理
proxy: 定义代理服务器的主机名称和端口
cancelToken: 指定用于取消请求的 cancel token
更多内容查看官方文档:Axios Docs
示例
const btns = document.getElementsByTagName('button');
const textarea = document.getElementsByTagName('textarea')[0];
// REQUEST
btns[0].onclick = function(){
axios.request({
url: 'http://127.0.0.1:3000/server',
method: 'GET',
}).then( response => {
console.log(response)
})
}
// GET
btns[1].onclick = function(){
axios.get( 'http://127.0.0.1:3000/server',{
params: {
a: 100,
b: 200
},
headers: {
name: 'custome-header'
}
}).then( response => {
console.log(response)
textarea.innerHTML = response.data
})
}
// POST
btns[2].onclick = function(){
axios.post( 'http://127.0.0.1:3000/server',{
a: 100,
b: 200
},{
headers: {
name: 'custome-header'
}
}
).then( response => {
console.log(response)
textarea.innerHTML = response.data
})
}
// AXIOS
btns[3].onclick = function(){
axios({
url: 'server',
method: 'post',
baseURL: 'http://127.0.0.1:3000/',
headers: {
'CustomeHeadet': 'custome-header'
},
params: {
user: 'admin',
password: '12345'
},
timeout: 5000
}).then( response => {
console.log(response)
textarea.innerHTML = response.data
})
}
Fetch API 发送 AJAX 请求
Fetch 是一种 HTTP 数据请求的方式,是 XMLHttpRequest 的一种替代方案。Fetch 不是 XMLHttpRequest 的进一步封装,而是原生JS。Fetch函数就是原生 JS ,没有使用 XMLHttpRequest 对象。
fetch(url[, config]);
config:请求的配置项
config 是一个对象,里面包裹 fetch 中的各种配置,主要配置包括:
method:请求使用的方法,如 GET、POST。
headers:请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
body:请求的 body 信息:可能是一个 Blob、BufferSource (en-US)、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
mode:请求的模式,如 cors、 no-cors 或者 same-origin。
credentials:请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie , 必须提供这个选项, 从 Chrome 50 开始, 这个属性也可以接受 FederatedCredential (en-US) 实例或是一个 PasswordCredential (en-US) 实例。
cache:请求的 cache 模式: default、 no-store、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
redirect:可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中默认使用follow(Chrome 47之前的默认值是manual)。
referrer:一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。
referrerPolicy: 指定 HTTP 头部 referer 字段的值。可能为:no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。
integrity:包括请求的 subresource integrity 值
注意:fetch 返回的是一个 Promise 对象
示例
const btns = document.getElementsByTagName('button');
const textarea = document.getElementsByTagName('textarea')[0];
// FETCH
btns[0].onclick = function(){
fetch('http://127.0.0.1:3000/server',{
method: 'GET',
headers:{
CustomeHeader: 'custome-header'
}
}).then(response => {
console.log(response)
return response.text()
}).then(response => {
console.log(response)
textarea.innerHTML = response
})
}
更多内容请查看:Fetch_API
Promise
上面 axios 及 fetch 中均使用了 Promise 对象用于发起异步请求,这里简单介绍下 Promise。
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。对象的状态不受外界影响,有以下三种状态:
pending: 待定,初始发起,尚未成功或失败
fulfilled: 兑现,操作成功完成
rejected: 拒绝,操作已经失败
注意:Promise 对象的状态一旦改变,就不会再变,任何时候都可以得到这个结果。
传统异步编程采用回调函数的方式,比如:fs 文件操作、数据库操作、AJAX、定时器等。回调函数的嵌套调用往往造成回调地狱。Promise 作为一种新的异步编程解决方案,支持链式调用,避免回调地狱。
静态方法
all(iterable):iterable 参数中的所有 Promise 对象都成功才成功,否则失败
allSettled(iterable):iterable 参数中的所有 Promise 对象都敲定后返回一个 Promise 数组对象,包含每个 Promise 的结果
any(iterable):iterable 参数中的所有 Promise 对象只要有一个成功就成功,否则失败
race(iterable):iterable 参数中的所有 Promise 对象第一个执行完毕后的结果立刻返回(谁先完以谁的为准)
reject(reason):返回一个状态为失败的 Promise 对象,并将给定的失败原因传递给对应的处理方法
resolve(value):返回一个状态为成功的 Promise 对象,并将给定的成功信息传递给对应的处理方法
原型方法
catch(reject):添加一个拒绝(reject) 回调到当前 Promise, 返回一个新的 Promise
then(resolve, reject):添加解决(resolve)和拒绝(reject)回调到当前 Promise, 返回一个新的 Promise
finally(finally):添加一个事件处理回调到当前 Promise,在原 Promise 解析完后,返回一个新的Promise
示例
const btns = document.getElementsByTagName('button');
const textarea = document.getElementsByTagName('textarea')[0];
// Promise
btns[0].onclick = function(){
const promise = new Promise((resolve, reject) => {
let n = Math.random() * 100;
if( n <= 50){
resolve(n); // 成功时的处理方法,可传递参数
}else{
reject(n); // 失败时的处理方法,可传递参数
}
})
promise.then((value) => {
// then 方法中的第一个参数为成功后的处理函数
console.log('恭喜,成功了!当前值为:' + value)
textarea.innerHTML = '成功时接收的参数值:' + value
},(reason) => {
// then 方法中的第二个参数为失败后的处理函数,也可用 catch 捕获错误值
console.log('抱歉,失败了!当前值为:' + reason)
textarea.innerHTML = '失败时接收的参数值:' + reason
})
}
更多内容请查看:Promise
async 与 await
async 返回一个 Promise 对象,并且 Promise 对象的结果为 async 函数的返回值
await 右侧一般为一个 Promise 对象,如果是 Promise 对象则返回 Promise 的值,否则直接返回值
注意:await 必须写在 async 函数中,async 函数中可以没有 await
示例
const btns = document.getElementsByTagName('button');
const textarea = document.getElementsByTagName('textarea')[0];
// async 与 await
btns[1].onclick= async function test(){
let promise = new Promise((resolve, reject)=>{
let n = Math.random() * 100;
if( n <= 50){
resolve('成功时的结果')
}else{
reject('错误时的原因')
}
})
try{
let result = await promise;
console.log(result) // 输出 '成功时的结果'
textarea.innerHTML = result
}catch(error){
// 使用 try...catch 捕捉错误
console.log(error)
textarea.innerHTML = error
}
}
更多内容请查看:Async 与 Await