十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

浏览器 API 【详解】fetch

浏览器 API 【详解】fetch fetch是浏览器原生网络请求API用来代替XMLHttpRequest返回 Promise不是第三方库不用安装。❗注意fetch只有网络异常才会 rejectHTTP 404/500 不会抛异常这点和axios不一样。基础语法fetch(resource,options).then(response{}).catch(error{})resourceurl字符串options配置对象method、headers、body等返回PromiseResponse对象Response 对象常用属性response.ok// boolean状态码200‑299为true404/500也是okfalse不会进catchresponse.status// http状态码 200、404、500response.json()// 解析响应为JSON返回Promiseresponse.text()// 获取原始文本response.blob()// 文件二进制response.headers// 响应头1. GET 请求最简单asyncfunctiongetDemo(){try{constresawaitfetch(https://jsonplaceholder.typicode.com/todos/1)// fetch 404/500不会抛出错误需要手动判断okif(!res.ok)thrownewError(HTTP错误:${res.status})constdataawaitres.json()console.log(data)}catch(err){// 网络断网、跨域才会走到这里console.error(请求失败,err)}}getDemo()2. POST 请求发送JSONPOST发JSON必须手动设置headers:{Content‑Type:application/json}body要JSON.stringify()asyncfunctionpostDemo(){constpayload{title:hello,body:world,userId:1}try{constresawaitfetch(https://jsonplaceholder.typicode.com/posts,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify(payload)})if(!res.ok)thrownewError(res.status)constdataawaitres.json()console.log(返回结果,data)}catch(e){console.error(e)}}postDemo()3. 提交表单 FormData上传文件/表单不要手动设置Content‑Type浏览器会自动带上boundaryasyncfunctionformDataDemo(){constformDatanewFormData()formData.append(username,zhangsan)// formData.append(file, fileObj) // 上传文件constresawaitfetch(/api/upload,{method:POST,body:formData})constdataawaitres.json()}4. 常用配置项完整示例fetch(url,{method:GET,// GET POST PUT DELETE PATCHheaders:{Content-Type:application/json,token:xxxxxx// 请求头携带token},body:JSON.stringify({a:1}),// GET不要写bodymode:cors,// cors、no‑cors、same‑origincredentials:include,// 携带cookieinclude跨域也带same‑origin仅同源signal:abortSignal,// 取消请求}) 取消 fetch 请求AbortController非常常用React组件卸载要取消请求防止setState在卸载组件执行报错asyncfunctionabortDemo(){constcontrollernewAbortController()constsignalcontroller.signal// 500ms后取消请求setTimeout(()controller.abort(),500)try{constresawaitfetch(https://jsonplaceholder.typicode.com/todos/1,{signal})constdataawaitres.json()console.log(data)}catch(err){if(err.nameAbortError){console.log(请求被手动取消)}}}abortDemo()React中使用组件卸载取消请求useEffect((){ const controller new AbortController() const signal controller.signal async function loadData(){ const res await fetch(/api/list, {signal}) } loadData() // effect清理函数组件卸载执行abort return () controller.abort() }, [])fetch vs axios 重点区别面试特性fetchaxios依赖浏览器原生无需安装第三方库错误处理404/500不会reject要判断ok非2xx直接进入catch拦截器无需要自己封装内置请求/响应拦截器超时无timeout靠AbortController模拟直接timeout配置转换数据手动 res.json()自动解析JSON取消请求AbortControllercancelToken / AbortController✨ 简易封装fetch项目里可以直接用asyncfunctionrequest(url,options{}){constbaseUrlconstheaders{Content-Type:application/json,...options.headers}// token示例 headers.Authorization Bearer ${localStorage.getItem(token)}constresawaitfetch(baseUrlurl,{...options,headers})if(!res.ok){thrownewError(http:${res.status})}returnres.json()}// 使用// request(/api/todo,{method:GET})// .then(dconsole.log(d))⚠️ 坑总结HTTP 4xx、5xx 不会触发catch必须手动判断!res.okPOST JSON必须JSON.stringify设置Content‑Type:application/jsonFormData不要手动设置Content‑Type组件卸载记得AbortController.abort()取消请求避免内存泄漏fetch不支持Node.js低版本Node18才内置fetch旧node需要安装node‑fetch包。实战范例重点留意范例代码中的多层错误处理useEffect((){// 使用原生 fetch 获取数据fetch(http://localhost:5293/api/products?keywordMacBook).then((response){if(!response.ok){// 如果响应状态码不是 2xx 范围的成功响应抛出错误throw newError(Failed to fetch data);}returnresponse.json();// 如果成功解析 JSON}).then((data){if(data.code!200)throw newError(data.message);returndata;});},[]);
返回列表