[{"data":1,"prerenderedAt":2928},["ShallowReactive",2],{"blog-taxonomies":3,"blog-stats":507,"post-2025\u002F2025-12-28-前端-关于网络请求xhrajaxfetchaxios":1083},[4,11,16,21,25,29,36,39,44,47,52,58,63,66,71,76,80,84,87,93,96,101,105,110,113,117,122,127,132,136,141,143,146,151,155,157,162,165,169,173,176,179,183,186,190,193,197,200,205,208,211,214,219,222,228,234,237,239,245,249,253,256,260,266,271,276,281,283,287,290,293,298,301,304,306,308,311,314,316,318,321,327,332,337,342,347,352,354,356,358,361,365,367,369,371,374,376,378,381,386,390,393,396,400,404,407,411,413,415,417,421,423,425,428,431,433,435,437,439,441,443,446,448,450,454,456,459,461,463,465,467,469,471,473,477,483,486,488,491,493,495,497,499,501,503,505],{"category":5,"tags":6},"笔记",[7,8,9,10],"QQ","插件","LiteLoader","美化",{"category":12,"tags":13},"其他",[14,15,10],"博客","IP签名",{"category":17,"tags":18},"杂谈",[19,20],"互联网","观点",{"category":5,"tags":22},[14,23,24],"GitHub","数据可视化",{"category":5,"tags":26},[14,27,28],"访问统计","不蒜子",{"category":30,"tags":31},"工具",[32,33,34,35],"Python","爬虫","选课脚本","广州大学",{"category":5,"tags":37},[38,5],"数学分析",{"category":40,"tags":41},"算法",[42,40,43],"数据结构","线性表",{"category":40,"tags":45},[42,46],"复习",{"category":5,"tags":48},[49,50,51],"高等代数","线性代数","知识点",{"category":5,"tags":53},[14,54,55,56,57],"Typora","PicGo","图床","Markdown",{"category":30,"tags":59},[60,61,62],"Jupyter","工具配置","中文",{"category":30,"tags":64},[65,61,10],"VSCode",{"category":30,"tags":67},[68,69,70,35],"路由器","OpenWrt","校园网",{"category":12,"tags":72},[73,74,75],"网络协议","Wireshark","DEVP2P",{"category":5,"tags":77},[73,74,78,79],"Lua","解码器",{"category":5,"tags":81},[82,5,83],"常微分方程","数学",{"category":5,"tags":85},[86,5,83],"概率论",{"category":30,"tags":88},[89,90,91,92],"Docker","WSL","Windows","磁盘清理",{"category":30,"tags":94},[32,33,95,35],"课程表",{"category":5,"tags":97},[14,98,99,100],"Hexo","Gitalk","评论系统",{"category":5,"tags":102},[14,103,98,104],"Obsidian","写作工具",{"category":12,"tags":106},[107,108,109],"课题研究","泊松分布","参数估计",{"category":12,"tags":111},[107,108,109,112],"组会",{"category":12,"tags":114},[109,115,108,116],"IM模型","统计学",{"category":17,"tags":118},[119,120,121],"软考","网络规划","信息系统项目管理",{"category":30,"tags":123},[124,125,126],"Arch Linux","AppImage","Linux",{"category":5,"tags":128},[129,130,131],"编程语言","计算机科学","内存管理",{"category":5,"tags":133},[134,135],"Canvas","前端",{"category":5,"tags":137},[14,138,139,140],"GitHub Actions","Vite","部署",{"category":5,"tags":142},[135],{"category":5,"tags":144},[135,145],"系统设计",{"category":5,"tags":147},[135,148,149,150],"安全","XSS","CSRF",{"category":152,"tags":153},"项目",[134,154],"PixiJS",{"category":152,"tags":156},null,{"category":40,"tags":158},[42,159,160,161],"栈","队列","JavaScript",{"category":40,"tags":163},[42,164,161],"哈希表",{"category":5,"tags":166},[167,161,168],"ES6","Set",{"category":40,"tags":170},[40,171,172],"动态规划","背包问题",{"category":40,"tags":174},[40,175],"滑动窗口",{"category":40,"tags":177},[42,178,161],"链表",{"category":40,"tags":180},[40,181,161,182],"ACM","面试",{"category":40,"tags":184},[40,161,185],"数据类型转换",{"category":40,"tags":187},[42,188,178,189],"顺序表","TypeScript",{"category":5,"tags":191},[135,154,134,192],"渲染",{"category":5,"tags":194},[135,195,134,196],"富文本编辑","wangEditor",{"category":40,"tags":198},[199,40,178],"力扣",{"category":5,"tags":201},[202,203,204,91],"DNS","加密","网络安全",{"category":5,"tags":206},[135,207],"Axios",{"category":5,"tags":209},[135,207,189,210],"接口封装",{"category":5,"tags":212},[135,213,145],"JWT",{"category":152,"tags":215},[134,216,217,154,218],"画布","React","项目开发",{"category":17,"tags":220},[221],"日志",{"category":5,"tags":223},[224,225,226,227],"Neo4j","图数据库","中心度分析","PageRank",{"category":12,"tags":229},[230,231,232,233],"论文","机器学习","随机森林","保险欺诈",{"category":5,"tags":235},[236],"人工智能",{"category":5,"tags":238},[231,40,32],{"category":12,"tags":240},[241,242,243,244],"共识算法","最长链","区块链","算法设计",{"category":5,"tags":246},[161,247,248,135],"闭包","作用域",{"category":5,"tags":250},[14,138,251,252],"RSS","自动化",{"category":30,"tags":254},[89,90,91,255],"安装",{"category":30,"tags":257},[258,91,259],"MSYS2","开发环境",{"category":5,"tags":261},[262,263,264,265],"团队协作","Git","Commit规范","代码审查",{"category":30,"tags":267},[268,269,270],"oh-my-posh","终端美化","CLI",{"category":5,"tags":272},[273,274,275],"上下文工程","Agent","RAG",{"category":5,"tags":277},[278,279,280],"前端工程化","技术选型","工程基建",{"category":5,"tags":282},[275],{"category":5,"tags":284},[285,286],"SDD","规格驱动开发",{"category":5,"tags":288},[289],"neovim",{"category":5,"tags":291},[292],"技术写作",{"category":5,"tags":294},[295,32,296,89,297],"FastAPI","后端","工程实践",{"category":152,"tags":299},[274,300],"Harness Engineering",{"category":5,"tags":302},[303],"RFC",{"category":152,"tags":305},[274,300,275],{"category":152,"tags":307},[274],{"category":40,"tags":309},[199,40,161,310],"两数之和",{"category":40,"tags":312},[199,40,161,313],"双指针",{"category":40,"tags":315},[199,40,161,178],{"category":40,"tags":317},[199,40,161,175],{"category":40,"tags":319},[199,40,161,320],"回溯",{"category":5,"tags":322},[323,324,325,326],"分布式处理与计算","Spark","Scala","RDD",{"category":5,"tags":328},[323,329,330,331],"线性回归","逻辑回归","监督学习",{"category":5,"tags":333},[323,334,335,336],"数值优化","牛顿法","收敛性",{"category":5,"tags":338},[323,339,340,341],"PCA","数据降维","正则化",{"category":5,"tags":343},[323,344,345,346],"聚类","层次聚类","K-Means",{"category":5,"tags":348},[323,349,350,351],"随机模拟","统计推断","EM算法",{"category":5,"tags":353},[24],{"category":5,"tags":355},[24],{"category":5,"tags":357},[24],{"category":40,"tags":359},[42,360],"图论",{"category":40,"tags":362},[42,363,364],"树","二叉树",{"category":40,"tags":366},[42,160],{"category":40,"tags":368},[42],{"category":40,"tags":370},[42,159],{"category":40,"tags":372},[42,40,373],"复杂度分析",{"category":40,"tags":375},[42,43,178],{"category":40,"tags":377},[42,43,188],{"category":40,"tags":379},[42,380],"基础概念",{"category":17,"tags":382},[383,384,385],"随记","照片","高中",{"category":17,"tags":387},[383,388,389],"团建","战地",{"category":17,"tags":391},[383,392],"生活",{"category":17,"tags":394},[383,395],"文学",{"category":17,"tags":397},[383,398,399],"SCP","模因",{"category":17,"tags":401},[383,402,403],"画集","艺术",{"category":17,"tags":405},[14,406,383],"写作",{"category":17,"tags":408},[383,409,410],"音乐","摇滚",{"category":17,"tags":412},[383,392],{"category":17,"tags":414},[383,409],{"category":17,"tags":416},[383,35,392],{"category":17,"tags":418},[383,419,420],"同人","手书",{"category":17,"tags":422},[383,392],{"category":17,"tags":424},[383,392],{"category":17,"tags":426},[383,427],"植物",{"category":17,"tags":429},[383,430],"读书",{"category":17,"tags":432},[383,392],{"category":17,"tags":434},[383,392],{"category":17,"tags":436},[383,392],{"category":17,"tags":438},[383,392],{"category":17,"tags":440},[383,392],{"category":17,"tags":442},[383,392],{"category":17,"tags":444},[14,445,383],"一周年",{"category":17,"tags":447},[383,392],{"category":17,"tags":449},[383,392],{"category":17,"tags":451},[35,452,453],"开源组织","SITE-193",{"category":17,"tags":455},[383,392],{"category":17,"tags":457},[383,458],"年末",{"category":17,"tags":460},[383,392],{"category":17,"tags":462},[383,392],{"category":17,"tags":464},[14,17],{"category":17,"tags":466},[383,392],{"category":17,"tags":468},[383,392],{"category":17,"tags":470},[383,392],{"category":17,"tags":472},[383,392],{"category":17,"tags":474},[383,475,476],"游戏","Control",{"category":30,"tags":478},[479,480,481,482],"Quadim","图像处理","四叉树","Rust",{"category":17,"tags":484},[14,485],"上线纪念",{"category":17,"tags":487},[383,395],{"category":30,"tags":489},[203,490],"测试",{"category":17,"tags":492},[383],{"category":17,"tags":494},[383,392],{"category":17,"tags":496},[383],{"category":5,"tags":498},[40],{"category":5,"tags":500},[40],{"category":5,"tags":502},[40],{"category":5,"tags":504},[40],{"category":5,"tags":506},[40],[508,512,516,520,524,528,532,536,540,544,548,552,556,560,564,568,572,576,579,583,587,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646,650,654,658,662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770,774,778,782,786,790,794,798,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889,893,897,901,904,907,911,915,919,923,927,930,934,938,942,946,950,954,957,961,965,969,973,977,981,984,988,992,996,1000,1004,1007,1011,1015,1019,1023,1027,1031,1035,1039,1043,1047,1051,1055,1059,1063,1067,1071,1075,1079],{"path":509,"words":510,"published":511,"date":156},"\u002Fposts\u002F2024\u002F2024-06-25-liteloaderqqnt",1296,"2024-06-25 11:03:08",{"path":513,"words":514,"published":515,"date":156},"\u002Fposts\u002F2024\u002F2024-06-26-ip签名",0,"2024-06-26 22:53:53",{"path":517,"words":518,"published":519,"date":156},"\u002Fposts\u002F2024\u002F2024-06-29-何加盐中文互联网正在加速崩塌",4853,"2024-06-29 00:47:13",{"path":521,"words":522,"published":523,"date":156},"\u002Fposts\u002F2024\u002F2024-07-12-github-chart",270,"2024-07-12 20:02:50",{"path":525,"words":526,"published":527,"date":156},"\u002Fposts\u002F2024\u002F2024-07-14-访客数统计",192,"2024-07-24 01:34:28",{"path":529,"words":530,"published":531,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-广大选课脚本",110,"2024-07-26 01:34:28",{"path":533,"words":534,"published":535,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数学分析笔记其二",14,"2024-07-26 23:54:02",{"path":537,"words":538,"published":539,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习其二",12856,"2024-07-26 02:48:08",{"path":541,"words":542,"published":543,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习相关",32856,"2024-07-26 02:24:14",{"path":545,"words":546,"published":547,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-线性代数与空间解析几何知识点全汇总",6110,"2024-07-26 03:27:55",{"path":549,"words":550,"published":551,"date":156},"\u002Fposts\u002F2024\u002F2024-07-31-typora-picgo-兰空图床打造markdown写作环境",311,"2024-07-31 12:56:23",{"path":553,"words":554,"published":555,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-jupyter配置中文",441,"2024-09-02 23:49:05",{"path":557,"words":558,"published":559,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-自定义vscode背景图片",100,"2024-09-02 23:39:00",{"path":561,"words":562,"published":563,"date":156},"\u002Fposts\u002F2024\u002F2024-09-03-制作gzhu校园网路由器",1423,"2024-09-03 23:43:18",{"path":565,"words":566,"published":567,"date":156},"\u002Fposts\u002F2024\u002F2024-09-26-09-25-2024",136,"2024-09-26 00:49:26",{"path":569,"words":570,"published":571,"date":156},"\u002Fposts\u002F2024\u002F2024-11-04-创建一个网络包解码器分析devp2p协议",1943,"2024-11-04 16:45:19",{"path":573,"words":574,"published":575,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记常微分",16,"2024-12-09 22:51:00",{"path":577,"words":574,"published":578,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记概率论","2025-03-09 22:51:00",{"path":580,"words":581,"published":582,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-windows下释放docker占用的wsl空间",164,"2025-03-01 13:54:15",{"path":584,"words":585,"published":586,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-爬虫实战-爬取广州大学课程表",774,"2025-03-01 14:55:48",{"path":588,"words":530,"published":589,"date":156},"\u002Fposts\u002F2025\u002F2025-04-03-hexo集成gitalk的问题","2025-04-03 14:26:34",{"path":591,"words":592,"published":593,"date":156},"\u002Fposts\u002F2025\u002F2025-09-22-记一次配置obsidian配合hexo写博客",92,"2025-09-22 16:47:52",{"path":595,"words":596,"published":597,"date":156},"\u002Fposts\u002F2025\u002F2025-10-24-10-20课题",204,"2025-10-24 08:15:01",{"path":599,"words":600,"published":601,"date":156},"\u002Fposts\u002F2025\u002F2025-11-02-组会朝花夕拾",501,"2025-11-02 18:56:59",{"path":603,"words":604,"published":605,"date":156},"\u002Fposts\u002F2025\u002F2025-11-05-基于随机加权推断模型im的参数估计算法",481,"2025-11-05 20:51:41",{"path":607,"words":608,"published":609,"date":156},"\u002Fposts\u002F2025\u002F2025-11-09-关于软考高项网规",884,"2025-11-09 19:54:52",{"path":611,"words":612,"published":613,"date":156},"\u002Fposts\u002F2025\u002F2025-11-17-arch-linux运行appimage相关",365,"2025-11-17 09:59:59",{"path":615,"words":616,"published":617,"date":156},"\u002Fposts\u002F2025\u002F2025-11-19-相关概念",2058,"2025-11-19 11:06:20",{"path":619,"words":620,"published":621,"date":156},"\u002Fposts\u002F2025\u002F2025-11-21-web可视化实践canvas",6393,"2025-11-21 14:50:48",{"path":623,"words":624,"published":625,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-使用-github-actions-自动部署基于vite的项目到-github-pages",272,"2025-11-23 01:59:24",{"path":627,"words":628,"published":629,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-关于前端包管理器npmpnpmyarn和bun",4890,"2025-11-22 21:21:15",{"path":631,"words":632,"published":633,"date":156},"\u002Fposts\u002F2025\u002F2025-11-23-undo-redo-机制具体实现",7839,"2025-11-23 19:15:00",{"path":635,"words":636,"published":637,"date":156},"\u002Fposts\u002F2025\u002F2025-11-27-前端安全-关于xss与crsf",1866,"2025-11-28 02:05:25",{"path":639,"words":640,"published":641,"date":156},"\u002Fposts\u002F2025\u002F2025-12-05-现代协同-2d-画布编辑器pixijs-v8",4285,"2025-12-05 02:00:16",{"path":643,"words":644,"published":645,"date":156},"\u002Fposts\u002F2025\u002F2025-12-07-杂谈-课题组系统设计",3710,"2025-12-07 21:09:33",{"path":647,"words":648,"published":649,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-javascript中的数组方法与栈stack和队列queue的实现",474,"2025-11-29 16:58:15",{"path":651,"words":652,"published":653,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript-实现哈希表",189,"2025-11-27 11:31:39",{"path":655,"words":656,"published":657,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript的set方法",332,"2025-12-25 15:26:18",{"path":659,"words":660,"published":661,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于动态规划(背包问题为例)",1238,"2025-11-17 18:24:04",{"path":663,"words":664,"published":665,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于滑动窗口",712,"2025-11-20 15:04:40",{"path":667,"words":668,"published":669,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于链表(javascript)",500,"2025-11-25 13:00:48",{"path":671,"words":672,"published":673,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-面试算法acm模式构建构建输入输出模板",2051,"2025-12-25 23:09:45",{"path":675,"words":676,"published":677,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascript-数字数组字符串的处理",483,"2025-12-26 11:20:25",{"path":679,"words":680,"published":681,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascripttypescript-的顺序表链表实现",446,"2025-12-26 12:16:12",{"path":683,"words":684,"published":685,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-1-实现基础yuan素渲染和状态控制",2136,"2025-12-28 01:23:08",{"path":687,"words":688,"published":689,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-2-实现富文本编辑",1838,"2025-12-28 02:58:47",{"path":691,"words":692,"published":693,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-算法刷题-关于链表操作",2135,"2025-12-27 16:12:42",{"path":695,"words":696,"published":697,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-配置dnscrypt-proxy实现加密dns服务windows",1899,"2025-11-15 01:06:37",{"path":699,"words":700,"published":701,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-关于网络请求xhrajaxfetchaxios",7788,"2025-10-28 15:48:46",{"path":703,"words":704,"published":705,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-接口封装与请求规范axios为例",2373,"2025-12-29 01:01:18",{"path":707,"words":708,"published":709,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-身份验证管理-基于-jwt-token-的实现",2709,"2025-11-23 22:04:41",{"path":711,"words":712,"published":713,"date":156},"\u002Fposts\u002F2025\u002F2025-12-29-记canvas画布项目开发",6254,"2025-12-29 04:52:15",{"path":715,"words":716,"published":717,"date":156},"\u002Fposts\u002F2025\u002Fabout-site",116,"2025-03-31 16:44:24",{"path":719,"words":720,"published":721,"date":156},"\u002Fposts\u002F2025\u002F使用neo4j图数据科学库gds进行中心度分析",143,"2025-04-02 23:37:24",{"path":723,"words":724,"published":725,"date":156},"\u002Fposts\u002F2026\u002F2026-01-03-论文实训草稿",10445,"2026-01-03 14:10:49",{"path":727,"words":728,"published":729,"date":156},"\u002Fposts\u002F2026\u002F2026-01-06-人工智能导论",11461,"2026-01-07 03:25:49",{"path":731,"words":732,"published":733,"date":156},"\u002Fposts\u002F2026\u002F2026-01-07-机器学习相关算法",82,"2026-01-08 02:28:13",{"path":735,"words":736,"published":737,"date":156},"\u002Fposts\u002F2026\u002F2026-01-16-关于低复杂度最长链共识算法设计",4466,"2026-01-16 10:33:23",{"path":739,"words":740,"published":741,"date":156},"\u002Fposts\u002F2026\u002F2026-01-19-杂记2026-01-19",5754,"2026-01-20 01:03:26",{"path":743,"words":744,"published":745,"date":156},"\u002Fposts\u002F2026\u002F2026-01-22-github-action-自动同步博客到-github-主页",1069,"2026-01-22 16:31:47",{"path":747,"words":748,"published":749,"date":156},"\u002Fposts\u002F2026\u002F2026-03-01-windows-wsl安装docker",257,"2026-03-01 20:55:31",{"path":751,"words":752,"published":753,"date":156},"\u002Fposts\u002F2026\u002F2026-03-14-关于-msys2",701,"2026-03-15 03:05:04",{"path":755,"words":756,"published":757,"date":156},"\u002Fposts\u002F2026\u002F2026-03-28-团队项目协作规范随记",2419,"2026-03-29 05:33:50",{"path":759,"words":760,"published":761,"date":156},"\u002Fposts\u002F2026\u002F2026-03-29-oh-my-posh配置分享",104,"2026-03-29 16:34:43",{"path":763,"words":764,"published":765,"date":156},"\u002Fposts\u002F2026\u002F2026-06-13-从上下文工程到-agent-harness-engineering",8840,"2026-06-13 21:06:20",{"path":767,"words":768,"published":769,"date":156},"\u002Fposts\u002F2026\u002F2026-07-13-简谈前端基建质量标准与ai友好建设",3814,"2026-07-13 21:06:20",{"path":771,"words":772,"published":773,"date":156},"\u002Fposts\u002F2026\u002F2026-07-15-agentic-rag-系统实践",13357,"2026-07-15 21:06:20",{"path":775,"words":776,"published":777,"date":156},"\u002Fposts\u002F2026\u002F2026-07-18-简谈sdd规范驱动开发-copy",4476,"2026-07-18 11:06:20",{"path":779,"words":780,"published":781,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-个人neovim配置分享",366,"2026-07-22 13:46:50",{"path":783,"words":784,"published":785,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-关于技术写作-设计文档",6763,"2026-07-20 13:46:50",{"path":787,"words":788,"published":789,"date":156},"\u002Fposts\u002F2026\u002F2026-07-29-fastapi-工程实践随记",3417,"2026-07-29 04:58:34",{"path":791,"words":792,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-06-19-rfc-liskin_code_agent",3563,"2026-06-19 15:18:20",{"path":795,"words":796,"published":797,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-07-25-rfc-glushkov_ogas",13461,"2026-07-28 23:46:50",{"path":799,"words":800,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-08-03-adr-ogas-arkhiv",2698,{"path":802,"words":803,"published":804,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002Frag\u002F2026-08-12-arkhiv_rag-vol-1",4366,"2026-08-12 15:18:20",{"path":806,"words":807,"published":808,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-25-力扣百题速练javascripttypescriptvol-1",3108,"2025-12-25 13:57:08",{"path":810,"words":811,"published":812,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-26-力扣百题速练javascripttypescriptvol-2",3185,"2025-12-26 13:57:08",{"path":814,"words":815,"published":816,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-28-力扣百题速练javascripttypescriptvol-3",2533,"2025-12-29 02:15:44",{"path":818,"words":819,"published":820,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-17-力扣百题速练javascripttypescriptvol-4",3024,"2026-01-17 22:53:01",{"path":822,"words":823,"published":824,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-19-力扣百题速练javascripttypescriptvol-5",293,"2026-01-19 15:15:12",{"path":826,"words":827,"published":828,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算spark系统与scala语言",4320,"2026-07-06 14:10:49",{"path":830,"words":831,"published":832,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算分类与回归分析",2081,"2026-07-07 12:40:29",{"path":834,"words":835,"published":836,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数值优化方法",2182,"2026-07-07 13:50:29",{"path":838,"words":839,"published":840,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数据降维",1583,"2026-07-07 21:50:29",{"path":842,"words":843,"published":844,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算聚类分析",1882,"2026-07-07 16:50:29",{"path":846,"words":847,"published":848,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算随机模拟与统计推断",2433,"2026-07-06 22:40:29",{"path":850,"words":851,"published":852,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-基本图像",10011,"2026-06-14 20:18:20",{"path":854,"words":855,"published":856,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-概论",10030,"2026-06-14 15:18:20",{"path":858,"words":859,"published":860,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-15-数据可视化-可视化库",2032,"2026-06-15 20:18:20",{"path":862,"words":863,"published":864,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-图",5451,"2025-04-15 20:48:06",{"path":866,"words":867,"published":868,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-树",4211,"2025-04-30 02:19:06",{"path":870,"words":871,"published":872,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-队列",921,"2025-04-11 15:30:08",{"path":874,"words":875,"published":876,"date":156},"\u002Fposts\u002F数据结构\u002F关于数据结构的一些想法",456,"2025-04-04 19:13:49",{"path":878,"words":879,"published":880,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-栈",920,"2025-04-18 00:17:37",{"path":882,"words":883,"published":884,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-算法复杂度",2153,"2025-04-05 16:09:55",{"path":886,"words":887,"published":888,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表链表",4572,"2025-04-06 00:24:40",{"path":890,"words":891,"published":892,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表顺序表",4191,"2025-04-05 22:09:59",{"path":894,"words":895,"published":896,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-绪论",2881,"2025-04-05 11:31:22",{"path":898,"words":899,"published":156,"date":900},"\u002Fposts\u002F杂记\u002F2023-12-26-2023年12月26日",7,"2023-12-26 23:51:33",{"path":902,"words":899,"published":156,"date":903},"\u002Fposts\u002F杂记\u002F2024-01-01-2024团建","2024-01-01 01:51:27",{"path":905,"words":581,"published":156,"date":906},"\u002Fposts\u002F杂记\u002F2024-01-09-随记","2024-01-09 20:50:35",{"path":908,"words":909,"published":156,"date":910},"\u002Fposts\u002F杂记\u002F2024-03-12-花名",5275,"2024-03-12 16:04:23",{"path":912,"words":913,"published":156,"date":914},"\u002Fposts\u002F杂记\u002F2024-04-15-逆模因",1353,"2024-04-15 00:26:16",{"path":916,"words":917,"published":156,"date":918},"\u002Fposts\u002F杂记\u002F2024-05-03-艺作",27,"2024-05-03 00:01:00",{"path":920,"words":921,"published":156,"date":922},"\u002Fposts\u002F杂记\u002F2024-05-21-关于博客",1720,"2024-02-21 23:21:11",{"path":924,"words":925,"published":156,"date":926},"\u002Fposts\u002F杂记\u002F2024-06-20-dnvrc维克多崔专访-2023",2036,"2024-06-20 00:28:39",{"path":928,"words":760,"published":156,"date":929},"\u002Fposts\u002F杂记\u002F2024-06-25-6月25日随记","2024-06-25 12:46:36",{"path":931,"words":932,"published":156,"date":933},"\u002Fposts\u002F杂记\u002F2024-06-25-歌名-想見星星",148,"2024-06-25 22:47:59",{"path":935,"words":936,"published":156,"date":937},"\u002Fposts\u002F杂记\u002F2024-07-11-桂花岗",6,"2024-07-11 00:28:17",{"path":939,"words":940,"published":156,"date":941},"\u002Fposts\u002F杂记\u002F2024-07-15-rolling-bocci",9,"2024-07-15 21:25:56",{"path":943,"words":944,"published":156,"date":945},"\u002Fposts\u002F杂记\u002F2024-07-22-七月九日",34,"2024-07-09 17:54:23",{"path":947,"words":948,"published":156,"date":949},"\u002Fposts\u002F杂记\u002F2024-07-22-六月随记",1052,"2024-07-22 01:03:19",{"path":951,"words":952,"published":156,"date":953},"\u002Fposts\u002F杂记\u002F2024-07-22-石菖蒲",41,"2024-07-10 01:26:05",{"path":955,"words":514,"published":156,"date":956},"\u002Fposts\u002F杂记\u002F2024-07-23-新书","2024-07-23 01:05:49",{"path":958,"words":959,"published":156,"date":960},"\u002Fposts\u002F杂记\u002F2024-07-29-年前",74,"2024-07-29 23:59:07",{"path":962,"words":963,"published":156,"date":964},"\u002Fposts\u002F杂记\u002F2024-07-30-周边",138,"2024-07-30 02:03:23",{"path":966,"words":967,"published":156,"date":968},"\u002Fposts\u002F杂记\u002F2024-07-31-2024-7-31日",185,"2024-07-31 01:21:52",{"path":970,"words":971,"published":156,"date":972},"\u002Fposts\u002F杂记\u002F2024-08-02-八月",1710,"2024-08-30 00:31:02",{"path":974,"words":975,"published":156,"date":976},"\u002Fposts\u002F杂记\u002F2024-09-01-九月",1484,"2024-09-26 16:30:15",{"path":978,"words":979,"published":156,"date":980},"\u002Fposts\u002F杂记\u002F2024-09-08-2024年9月8日",97,"2024-09-08 13:59:36",{"path":982,"words":514,"published":156,"date":983},"\u002Fposts\u002F杂记\u002F2024-09-19-博客站的一周年","2024-09-18 23:36:24",{"path":985,"words":986,"published":156,"date":987},"\u002Fposts\u002F杂记\u002F2024-10-03-十月",1028,"2024-10-31 23:54:27",{"path":989,"words":990,"published":156,"date":991},"\u002Fposts\u002F杂记\u002F2024-11-04-十一月",2134,"2024-11-30 00:04:39",{"path":993,"words":994,"published":156,"date":995},"\u002Fposts\u002F杂记\u002F2024-11-10-gzhu-site-193",80,"2024-11-10 19:19:12",{"path":997,"words":998,"published":156,"date":999},"\u002Fposts\u002F杂记\u002F2024-12-01-十二月",455,"2024-12-30 23:13:47",{"path":1001,"words":1002,"published":156,"date":1003},"\u002Fposts\u002F杂记\u002F2024-12-21-年末",23,"2024-12-21 23:21:49",{"path":1005,"words":522,"published":156,"date":1006},"\u002Fposts\u002F杂记\u002F2025-01-30-一月","2025-01-30 23:44:41",{"path":1008,"words":1009,"published":156,"date":1010},"\u002Fposts\u002F杂记\u002F2025-03-01-二月",224,"2025-02-28 00:11:08",{"path":1012,"words":1013,"published":156,"date":1014},"\u002Fposts\u002F杂记\u002F2025-03-01-博客杂谈",344,"2025-03-01 16:03:18",{"path":1016,"words":1017,"published":156,"date":1018},"\u002Fposts\u002F杂记\u002F2025-03-05-三月",2090,"2025-03-05 19:17:28",{"path":1020,"words":1021,"published":156,"date":1022},"\u002Fposts\u002F杂记\u002F2025-07-10-七月",361,"2025-07-10 22:04:32",{"path":1024,"words":1025,"published":156,"date":1026},"\u002Fposts\u002F杂记\u002F2025-09-21-九月",781,"2025-09-21 20:53:37",{"path":1028,"words":1029,"published":156,"date":1030},"\u002Fposts\u002F杂记\u002F2025-10-09-十月",591,"2025-10-09 00:35:07",{"path":1032,"words":1033,"published":156,"date":1034},"\u002Fposts\u002F杂记\u002Fcontrol",13,"2023-09-25 13:03:59",{"path":1036,"words":1037,"published":156,"date":1038},"\u002Fposts\u002F杂记\u002Fquadim四叉树图像处理",1094,"2023-10-21 11:27:06",{"path":1040,"words":1041,"published":156,"date":1042},"\u002Fposts\u002F杂记\u002Fsuccess",24,"2023-09-22 15:59:07",{"path":1044,"words":1045,"published":156,"date":1046},"\u002Fposts\u002F杂记\u002F三光年",295,"2023-11-18 04:18:40",{"path":1048,"words":1049,"published":156,"date":1050},"\u002Fposts\u002F杂记\u002F加密测试",961,"2023-11-21 14:24:01",{"path":1052,"words":1053,"published":156,"date":1054},"\u002Fposts\u002F杂记\u002F啊啊啊啊啊啊啊",54,"2023-09-20 17:29:33",{"path":1056,"words":1057,"published":156,"date":1058},"\u002Fposts\u002F杂记\u002F杂谈",124,"2023-09-25 23:11:32",{"path":1060,"words":1061,"published":156,"date":1062},"\u002Fposts\u002F杂记\u002F艹",25,"2023-10-21 17:40:43",{"path":1064,"words":1065,"published":1066,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习卷积神经网络",3168,"2026-06-07 11:23:08",{"path":1068,"words":1069,"published":1070,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习循环神经网络",2348,"2026-06-07 11:33:08",{"path":1072,"words":1073,"published":1074,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习改进学习方法",3360,"2026-06-07 10:13:08",{"path":1076,"words":1077,"published":1078,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习深度生成模型",2727,"2026-06-07 11:43:08",{"path":1080,"words":1081,"published":1082,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习神经网络基础",3205,"2026-06-07 10:03:08",{"id":1084,"title":1085,"abbrlink":1086,"body":1087,"category":5,"cover":156,"date":156,"description":1098,"extension":2918,"mathjax":2919,"meta":2920,"navigation":2919,"path":699,"published":701,"readingMinutes":2923,"seo":2924,"stem":2925,"sticky":156,"swiper_index":156,"tags":2926,"updated":156,"words":700,"__hash__":2927},"posts\u002Fposts\u002F2025\u002F2025-12-28-前端-关于网络请求（XHR、Ajax、Fetch、Axios）.md","2025-10-28 关于前端网络请求（XHR、Ajax、Fetch、Axios）","61262",{"type":1088,"value":1089,"toc":2889},"minimark",[1090,1095,1099,1102,1130,1133,1136,1140,1143,1155,1158,1194,1198,1201,1211,1221,1227,1233,1239,1245,1251,1257,1263,1269,1272,1278,1304,1307,1316,1324,1329,1337,1342,1358,1363,1371,1377,1385,1391,1397,1403,1406,1413,1419,1432,1442,1449,1455,1463,1470,1476,1485,1491,1499,1510,1516,1519,1534,1537,1543,1588,1600,1603,1605,1608,1611,1661,1667,1670,1673,1691,1697,1709,1715,1727,1733,1745,1751,1763,1769,1773,1776,1779,1787,1793,1800,1806,1814,1820,1828,1834,1846,1852,1860,1866,1878,1881,1884,1887,1893,1896,1902,1905,1936,1938,1940,1943,1946,1949,1952,1978,1982,1988,1993,1999,2002,2015,2024,2037,2058,2063,2069,2121,2123,2126,2182,2188,2194,2200,2236,2239,2242,2248,2279,2282,2288,2297,2322,2335,2341,2343,2350,2356,2359,2362,2382,2388,2391,2402,2405,2454,2457,2465,2468,2474,2492,2495,2498,2548,2551,2557,2569,2572,2582,2588,2605,2609,2615,2638,2644,2660,2674,2680,2691,2694,2701,2707,2718,2728,2732,2738,2741,2747,2750,2764,2767,2777,2783,2789,2795,2801,2807,2813,2816,2819,2825,2844,2854,2857,2863,2869,2878,2884,2886],[1091,1092,1094],"h1",{"id":1093},"xhrajaxfetchaxios","XHR、Ajax、Fetch、Axios",[1096,1097,1098],"p",{},"当涉及前端网络请求时，有许多工具\u002F技术可供选择，包括 Fetch、Axios、Ajax 和 XHR 等。这些技术在发送和处理HTTP请求方面提供了不同的功能和方法。本文将深入探讨这些技术的特点、优势和用法，帮你更好地理解并选择最适合项目需求的技术。",[1096,1100,1101],{},"Fetch、Axios、Ajax 和XHR都是前端用于发送HTTP请求的工具或技术：",[1103,1104,1105,1113,1119,1125],"ul",{},[1106,1107,1108,1112],"li",{},[1109,1110,1111],"strong",{},"XHR","：一种在浏览器中用于与服务器进行异步通信的API，通过发送HTTP请求并处理服务器返回的数据，实现页面的无刷新更新和动态交互。",[1106,1114,1115,1118],{},[1109,1116,1117],{},"Ajax","：通过在浏览器和服务器之间进行异步通信，实现部分页面更新和动态交互，提升用户体验；可以在不重新加载整个页面的情况下，通过JavaScript发送HTTP请求到服务器，并处理服务器返回的数据；减少带宽消耗，提高页面加载速度；提高用户交互性，实现更多的动态效果和实时更新。",[1106,1120,1121,1124],{},[1109,1122,1123],{},"Fetch","：一种现代化的网络请求方法，通过使用 Promise 处理异步操作，简洁而直观地发送HTTP请求、处理响应，并支持各种功能和API，如设置请求头、传递参数、处理流数据、上传下载文件等。",[1106,1126,1127,1129],{},[1109,1128,207],{},"：一个基于Promise的现代化HTTP客户端，是目前最流行的 HTTP 客户端，可以在浏览器和Node.js环境中发送HTTP请求，并具有拦截请求和响应、支持并发请求、提供丰富的API等功能。",[1096,1131,1132],{},"下面就来看看这些技术都是怎么用的，以及都有什么特点",[1134,1135],"hr",{},[1137,1138,1111],"h2",{"id":1139},"xhr",[1096,1141,1142],{},"XMLHttpRequest 是一个内置的 JavaScript 对象，XMLHttpRequest（XHR）对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL，获取数据。这允许网页在不影响用户操作的情况下，更新页面的局部内容。",[1096,1144,1145,1146,1150,1151,1154],{},"XMLHttpRequest 在 AJAX 编程中被大量使用。尽管名称包含XML，XMLHttpRequest 也可以用于获取任何类型的数据，而不仅仅是 XML。它甚至支持 HTTP 以外的协议（包括 ",[1147,1148,1149],"code",{},"file:\u002F\u002F"," 和 ",[1147,1152,1153],{},"FTP","）。",[1096,1156,1157],{},"XMLHttpRequest 存在一些缺点：",[1103,1159,1160,1166,1172,1182,1188],{},[1106,1161,1162,1165],{},[1109,1163,1164],{},"语法复杂性","：使用原始的 XMLHttpRequest 进行复杂的 AJAX 请求需要编写更多的代码，并手动处理状态管理、错误处理等方面的逻辑。相比之下，Axios 和 Fetch API 提供了更简单和直观的语法，使得发送和处理 HTTP 请求更加方便。",[1106,1167,1168,1171],{},[1109,1169,1170],{},"功能限制","：XHR 提供的功能相对较少，需要手动设置请求头、处理超时、取消请求等。而 Axios 和 Fetch API 提供了更丰富的功能，如拦截请求和响应、自动转换数据格式、请求取消等。",[1106,1173,1174,1177,1178,1181],{},[1109,1175,1176],{},"XSRF（跨站请求伪造）保护","：在 Axios 中，可以通过设置 ",[1147,1179,1180],{},"withCredentials"," 选项来自动处理 XSRF 保护。然而，在 XMLHttpRequest 和 Fetch API 中，需要手动设置请求头来实现类似的保护。",[1106,1183,1184,1187],{},[1109,1185,1186],{},"错误处理","：XHR 的错误处理较为繁琐，需要在回调函数中进行错误判断。而 Axios 和 Fetch API 使用 Promise 和 async\u002Fawait 语法，能够更便捷地处理请求和响应的错误。",[1106,1189,1190,1193],{},[1109,1191,1192],{},"仅限于浏览器环境","：XMLHttpRequest 是浏览器提供的 API，因此只能在浏览器环境中使用，无法在其他环境中（如服务器端）直接使用。",[1195,1196,1197],"h3",{"id":1197},"请求步骤",[1096,1199,1200],{},"使用 XMLHttpRequest 发送请求的步骤如下：",[1202,1203,1204],"ol",{},[1106,1205,1206,1207,1210],{},"创建",[1147,1208,1209],{},"XMLHttpRequest","对象：",[1212,1213,1219],"pre",{"className":1214,"code":1216,"language":1217,"meta":1218},[1215],"language-javascript","let xhr = new XMLHttpRequest();\n","javascript","",[1147,1220,1216],{"__ignoreMap":1218},[1202,1222,1224],{"start":1223},2,[1106,1225,1226],{},"设置请求参数：",[1212,1228,1231],{"className":1229,"code":1230,"language":1217,"meta":1218},[1215],"xhr.open(\"GET\", \"https:\u002F\u002Fexample.com\u002Fapi\u002Fdata\", true);\n",[1147,1232,1230],{"__ignoreMap":1218},[1202,1234,1236],{"start":1235},3,[1106,1237,1238],{},"设置请求头（可选）：",[1212,1240,1243],{"className":1241,"code":1242,"language":1217,"meta":1218},[1215],"xhr.setRequestHeader(\"Content-Type\", \"application\u002Fjson\");\n",[1147,1244,1242],{"__ignoreMap":1218},[1202,1246,1248],{"start":1247},4,[1106,1249,1250],{},"监听状态变化：",[1212,1252,1255],{"className":1253,"code":1254,"language":1217,"meta":1218},[1215],"xhr.onreadystatechange = () => {\n    if (xhr.readyState === 4) {\n        if (xhr.status === 200) {\n            \u002F\u002F 请求成功，处理响应\n            console.log(xhr.responseText);\n        } else {\n            \u002F\u002F 请求失败\n            console.error(\"请求失败\");\n        }\n    }\n};\n",[1147,1256,1254],{"__ignoreMap":1218},[1202,1258,1260],{"start":1259},5,[1106,1261,1262],{},"发送请求：",[1212,1264,1267],{"className":1265,"code":1266,"language":1217,"meta":1218},[1215],"xhr.send();\n",[1147,1268,1266],{"__ignoreMap":1218},[1096,1270,1271],{},"完整代码如下：",[1212,1273,1276],{"className":1274,"code":1275,"language":1217,"meta":1218},[1215],"var xhr = new XMLHttpRequest();\nxhr.open(\"GET\", \"https:\u002F\u002Fapi.example.com\u002Fdata\", true);\n\nxhr.onreadystatechange = () => {\n    if (xhr.readyState === 4) {\n        if (xhr.status === 200) {\n            \u002F\u002F 请求成功，处理响应\n            console.log(xhr.responseText);\n        } else {\n            \u002F\u002F 请求失败\n            console.error(\"请求失败\");\n        }\n    }\n};\n\nxhr.send();\n",[1147,1277,1275],{"__ignoreMap":1218},[1096,1279,1280,1281,1283,1284,1287,1288,1291,1292,1295,1296,1299,1300,1303],{},"这里创建了一个",[1147,1282,1209],{},"对象，并使用",[1147,1285,1286],{},"open()","方法设置了一个GET请求类型和URL。然后，通过监听",[1147,1289,1290],{},"onreadystatechange","事件来判断请求的状态并处理响应。当",[1147,1293,1294],{},"readyState","为4时，表示请求已完成，此时可以通过",[1147,1297,1298],{},"status","属性判断请求是否成功（200表示成功）。如果成功，可以通过",[1147,1301,1302],{},"responseText","属性获取服务器返回的数据进行处理。如果失败，将到控制台输出错误信息。",[1195,1305,1306],{"id":1306},"open",[1096,1308,1309,1310,1312,1313,1315],{},"XMLHttpRequest 的 ",[1147,1311,1286],{}," 方法用于初始化一个请求。",[1147,1314,1286],{}," 方法接受三个必填参数和一个可选参数，它们是：",[1202,1317,1318],{},[1106,1319,1320,1323],{},[1109,1321,1322],{},"method",": 表示请求的 HTTP 方法，例如 GET、POST、PUT 等。",[1212,1325,1327],{"className":1326,"code":1230,"language":1217,"meta":1218},[1215],[1147,1328,1230],{"__ignoreMap":1218},[1202,1330,1331],{"start":1223},[1106,1332,1333,1336],{},[1109,1334,1335],{},"url",": 表示请求的 URL 地址。",[1212,1338,1340],{"className":1339,"code":1230,"language":1217,"meta":1218},[1215],[1147,1341,1230],{"__ignoreMap":1218},[1202,1343,1344],{"start":1235},[1106,1345,1346,1349,1350,1353,1354,1357],{},[1109,1347,1348],{},"async",": 表示请求是否异步执行，即是否使用异步模式。默认为 ",[1147,1351,1352],{},"true","，表示异步执行；f",[1147,1355,1356],{},"alse"," 表示同步执行。",[1212,1359,1361],{"className":1360,"code":1230,"language":1217,"meta":1218},[1215],[1147,1362,1230],{"__ignoreMap":1218},[1202,1364,1365],{"start":1247},[1106,1366,1367,1370],{},[1109,1368,1369],{},"username"," (可选): 表示用于进行 HTTP 认证的用户名。",[1212,1372,1375],{"className":1373,"code":1374,"language":1217,"meta":1218},[1215],"xhr.open(\"GET\", \"https:\u002F\u002Fexample.com\u002Fapi\u002Fdata\", true, \"username\");\n",[1147,1376,1374],{"__ignoreMap":1218},[1202,1378,1379],{"start":1259},[1106,1380,1381,1384],{},[1109,1382,1383],{},"password"," (可选): 表示用于进行 HTTP 认证的密码。",[1212,1386,1389],{"className":1387,"code":1388,"language":1217,"meta":1218},[1215],"xhr.open(\"GET\", \"https:\u002F\u002Fexample.com\u002Fapi\u002Fdata\", true, \"username\", \"password\");\n",[1147,1390,1388],{"__ignoreMap":1218},[1096,1392,1393,1394,1396],{},"综合起来，",[1147,1395,1286],{}," 方法的完整语法如下：",[1212,1398,1401],{"className":1399,"code":1400,"language":1217,"meta":1218},[1215],"xhr.open(method, url, async, username, password);\n",[1147,1402,1400],{"__ignoreMap":1218},[1195,1404,1405],{"id":1405},"请求头和响应头",[1096,1407,1408,1409,1412],{},"可以使用 ",[1147,1410,1411],{},"setRequestHeader()"," 方法设置 XMLHttpRequest 的请求头。这个方法接受两个参数：头字段的名称和值。",[1212,1414,1417],{"className":1415,"code":1416,"language":1217,"meta":1218},[1215],"xhr.setRequestHeader(\"Content-Type\", \"application\u002Fjson\");\nxhr.setRequestHeader(\"Authorization\", \"Bearer token123\");\n",[1147,1418,1416],{"__ignoreMap":1218},[1096,1420,1421,1422,1424,1425,1150,1428,1431],{},"这里使用 ",[1147,1423,1411],{}," 方法设置了两个请求头：",[1147,1426,1427],{},"Content-Type",[1147,1429,1430],{},"Authorization","。第一个参数是头字段的名称，第二个参数是头字段的值。",[1096,1433,1408,1434,1437,1438,1441],{},[1147,1435,1436],{},"getResponseHeader()"," 方法或者 ",[1147,1439,1440],{},"getAllResponseHeaders()"," 方法来获取 XMLHttpRequest 的响应头。",[1103,1443,1444],{},[1106,1445,1446,1448],{},[1147,1447,1436],{},"：通过指定头字段的名称，可以获取指定的响应头字段的值。",[1212,1450,1453],{"className":1451,"code":1452,"language":1217,"meta":1218},[1215],"const contentType = xhr.getResponseHeader(\"Content-Type\");\n",[1147,1454,1452],{"__ignoreMap":1218},[1096,1456,1421,1457,1459,1460,1462],{},[1147,1458,1436],{}," 方法获取了名为 ",[1147,1461,1427],{},"的响应头字段的值。",[1103,1464,1465],{},[1106,1466,1467,1469],{},[1147,1468,1440],{},"：该方法返回一个包含所有响应头信息的字符串。",[1212,1471,1474],{"className":1472,"code":1473,"language":1217,"meta":1218},[1215],"const headers = xhr.getAllResponseHeaders();\n",[1147,1475,1473],{"__ignoreMap":1218},[1096,1477,1421,1478,1480,1481,1484],{},[1147,1479,1440],{}," 方法获取了所有响应头信息，并将其存储在名为 ",[1147,1482,1483],{},"headers"," 的变量中。",[1096,1486,1487,1488,1490],{},"这里返回的 ",[1147,1489,1483],{}," 是一个包含所有响应头信息的字符串。该字符串中每一行表示一个响应头字段，具有以下形式：",[1212,1492,1497],{"className":1493,"code":1495,"language":1496},[1494],"language-text","HeaderName: HeaderValue\n","text",[1147,1498,1495],{"__ignoreMap":1218},[1096,1500,1501,1502,1150,1504,1506,1507,1509],{},"例如，如果响应头中包含 ",[1147,1503,1427],{},[1147,1505,1430],{}," 字段，那么返回的 ",[1147,1508,1483],{}," 字符串可能如下所示：",[1212,1511,1514],{"className":1512,"code":1513,"language":1496},[1494],"Content-Type: application\u002Fjson\nAuthorization: Bearer token123\n",[1147,1515,1513],{"__ignoreMap":1218},[1096,1517,1518],{},"可以使用适当的方法（如字符串解析）将这个字符串进行进一步处理，以获取特定的响应头字段的名称和值。",[1096,1520,1521,1522,1524,1525,1527,1528,1530,1531,1533],{},"注意，要在调用 ",[1147,1523,1286],{}," 方法之后、发送请求之前使用 ",[1147,1526,1411],{}," 方法来设置请求头，以确保设置能够生效。同样，要在接收到响应之后才能使用 ",[1147,1529,1436],{}," 或 ",[1147,1532,1440],{}," 来获取响应头信息。",[1195,1535,1294],{"id":1536},"readystate",[1096,1538,1539,1540,1542],{},"上面示例中的 ",[1147,1541,1294],{}," 是 XMLHttpRequest 对象的一个属性，用于表示请求的状态。该属性有以下五种可能的取值：",[1202,1544,1545,1554,1566,1576,1582],{},[1106,1546,1547,1550,1551,1553],{},[1109,1548,1549],{},"0 (未初始化)",": XMLHttpRequest 对象已创建，但尚未调用 ",[1147,1552,1306],{}," 方法。",[1106,1555,1556,1559,1560,1562,1563,1553],{},[1109,1557,1558],{},"1 (载入中)",": ",[1147,1561,1306],{}," 方法已调用，但尚未调用 ",[1147,1564,1565],{},"send",[1106,1567,1568,1571,1572,1575],{},[1109,1569,1570],{},"2 (载入完成)",": s",[1147,1573,1574],{},"end"," 方法已调用，并且响应头和响应状态已经可用。",[1106,1577,1578,1581],{},[1109,1579,1580],{},"3 (交互中)",": 正在接收响应数据，此时部分响应内容可能已经可以访问了。",[1106,1583,1584,1587],{},[1109,1585,1586],{},"4 (完成)",": 响应数据接收完成，整个请求过程已经完全结束。",[1096,1589,1590,1591,1593,1594,1530,1596,1599],{},"通常情况下，我们主要关注 readyState 为 4 的状态，即请求完成状态。在这个状态下，我们可以通过检查 ",[1147,1592,1298],{}," 属性来获取请求的结果（比如响应状态码），并通过 ",[1147,1595,1302],{},[1147,1597,1598],{},"responseXML"," 属性来获取服务器返回的数据。",[1096,1601,1602],{},"注意，readyState 属性是只读的，我们不能直接修改它的值。它会在请求过程中自动更新，我们可以通过监听 readystatechange 事件来进行相应的处理。",[1195,1604,1298],{"id":1298},[1096,1606,1607],{},"status 是 XMLHttpRequest 对象的一个属性，用于表示 HTTP 状态码。",[1096,1609,1610],{},"HTTP 状态码是服务器对请求处理的结果进行响应的标准化数字代码。常见的一些 HTTP 状态码包括：",[1103,1612,1613,1619,1625,1631,1637,1643,1649,1655],{},[1106,1614,1615,1618],{},[1109,1616,1617],{},"200 OK","：表示请求成功并返回所请求的数据。",[1106,1620,1621,1624],{},[1109,1622,1623],{},"201 Created","：表示请求成功并在服务器上创建了新资源。",[1106,1626,1627,1630],{},[1109,1628,1629],{},"204 No Content","：表示请求成功，但响应中无返回的内容。",[1106,1632,1633,1636],{},[1109,1634,1635],{},"400 Bad Request","：表示请求有语法错误或参数错误，服务器无法理解。",[1106,1638,1639,1642],{},[1109,1640,1641],{},"401 Unauthorized","：表示请求未经授权，需要用户进行身份验证。",[1106,1644,1645,1648],{},[1109,1646,1647],{},"403 Forbidden","：表示服务器拒绝请求，通常是因为请求的资源没有访问权限。",[1106,1650,1651,1654],{},[1109,1652,1653],{},"404 Not Found","：表示请求的资源不存在。",[1106,1656,1657,1660],{},[1109,1658,1659],{},"500 Internal Server Error","：表示服务器内部发生错误，无法完成请求。",[1096,1662,1663,1664,1666],{},"在使用 XMLHttpRequest 发送请求后，可以通过检查 ",[1147,1665,1298],{}," 属性来获取服务器对请求的响应状态码，并根据不同的状态码进行相应的处理。",[1195,1668,1669],{"id":1669},"事件属性",[1096,1671,1672],{},"XMLHttpRequest (XHR) 对象具有以下常用的事件属性：",[1202,1674,1675],{},[1106,1676,1677,1679,1680,1682,1683,1686,1687,1690],{},[1109,1678,1290],{},": 当 ",[1147,1681,1294],{}," 属性发生变化时触发该事件。可以使用 ",[1147,1684,1685],{},"xhr.onreadystatechange"," 属性来指定处理状态变化的回调函数。在每次状态变化时都会触发该事件，可以通过检查 ",[1147,1688,1689],{},"xhr.readyState"," 属性来确定当前的状态。",[1212,1692,1695],{"className":1693,"code":1694,"language":1217,"meta":1218},[1215],"xhr.onreadystatechange = () => {\n    if (xhr.readyState === 4) {\n        \u002F\u002F 请求已完成\n        if (xhr.status === 200) {\n            \u002F\u002F 请求成功\n        } else {\n            \u002F\u002F 请求失败\n        }\n    } else {\n        \u002F\u002F 请求进行中\n    }\n};\n",[1147,1696,1694],{"__ignoreMap":1218},[1202,1698,1699],{"start":1223},[1106,1700,1701,1704,1705,1708],{},[1147,1702,1703],{},"onload:"," 当请求成功完成并且响应数据完全加载时触发该事件。可以使用 ",[1147,1706,1707],{},"xhr.onload"," 属性来指定处理成功加载的回调函数。通常在这个事件中获取和处理响应数据。",[1212,1710,1713],{"className":1711,"code":1712,"language":1217,"meta":1218},[1215],"xhr.onload = () => {\n    \u002F\u002F 获取和处理响应数据\n    const responseData = JSON.parse(xhr.responseText);\n    \u002F\u002F 其他操作...\n};\n",[1147,1714,1712],{"__ignoreMap":1218},[1202,1716,1717],{"start":1235},[1106,1718,1719,1722,1723,1726],{},[1147,1720,1721],{},"onerror",": 当请求发生错误时触发该事件。可以使用 ",[1147,1724,1725],{},"xhr.onerror"," 属性来指定处理错误的回调函数。常见的错误包括网络错误、无法完成请求等。",[1212,1728,1731],{"className":1729,"code":1730,"language":1217,"meta":1218},[1215],"xhr.onerror = () => {\n    \u002F\u002F 处理错误逻辑\n};\n",[1147,1732,1730],{"__ignoreMap":1218},[1202,1734,1735],{"start":1247},[1106,1736,1737,1740,1741,1744],{},[1147,1738,1739],{},"onprogress",": 在数据传输过程中持续触发，用于追踪请求的进度。可以使用 ",[1147,1742,1743],{},"xhr.onprogress"," 属性来指定处理进度的回调函数。",[1212,1746,1749],{"className":1747,"code":1748,"language":1217,"meta":1218},[1215],"xhr.onprogress = (event) => {\n    \u002F\u002F 处理进度逻辑\n};\n",[1147,1750,1748],{"__ignoreMap":1218},[1202,1752,1753],{"start":1259},[1106,1754,1755,1758,1759,1762],{},[1147,1756,1757],{},"ontimeout","： 当请求超时时触发该事件。可以使用 ",[1147,1760,1761],{},"xhr.ontimeout"," 属性来指定处理超时的回调函数。",[1212,1764,1767],{"className":1765,"code":1766,"language":1217,"meta":1218},[1215],"xhr.ontimeout = () => {\n    \u002F\u002F 处理超时逻辑\n};\n",[1147,1768,1766],{"__ignoreMap":1218},[1195,1770,1772],{"id":1771},"responsetype","responseType",[1096,1774,1775],{},"responseType 是 XMLHttpRequest 对象的属性，用于指定响应的数据类型。它决定了如何解析从服务器返回的响应数据。",[1096,1777,1778],{},"常见的 responseType 值包括：",[1202,1780,1781],{},[1106,1782,1783,1786],{},[1109,1784,1785],{},"\"\" (默认值)",": 表示响应的数据类型是字符串。",[1212,1788,1791],{"className":1789,"code":1790,"language":1217,"meta":1218},[1215],"xhr.responseType = \"\";\n",[1147,1792,1790],{"__ignoreMap":1218},[1202,1794,1795],{"start":1223},[1106,1796,1797,1786],{},[1109,1798,1799],{},"\"text\"",[1212,1801,1804],{"className":1802,"code":1803,"language":1217,"meta":1218},[1215],"xhr.responseType = \"text\";\n",[1147,1805,1803],{"__ignoreMap":1218},[1202,1807,1808],{"start":1235},[1106,1809,1810,1813],{},[1109,1811,1812],{},"\"json\"",": 表示响应的数据类型是 JSON 对象，会自动将响应数据解析为 JavaScript 对象。",[1212,1815,1818],{"className":1816,"code":1817,"language":1217,"meta":1218},[1215],"xhr.responseType = \"json\";\n",[1147,1819,1817],{"__ignoreMap":1218},[1202,1821,1822],{"start":1247},[1106,1823,1824,1827],{},[1109,1825,1826],{},"\"document\"",": 表示响应的数据类型是 XML 文档对象，会自动将响应数据解析为 XML 文档对象。",[1212,1829,1832],{"className":1830,"code":1831,"language":1217,"meta":1218},[1215],"xhr.responseType = \"document\";\n",[1147,1833,1831],{"__ignoreMap":1218},[1202,1835,1836],{"start":1259},[1106,1837,1838,1841,1842,1845],{},[1109,1839,1840],{},"\"arraybuffer\"",": 表示响应的数据类型是 ",[1147,1843,1844],{},"ArrayBuffer"," 对象，适用于二进制数据的传输和处理。",[1212,1847,1850],{"className":1848,"code":1849,"language":1217,"meta":1218},[1215],"xhr.responseType = \"arraybuffer\";\n",[1147,1851,1849],{"__ignoreMap":1218},[1202,1853,1854],{"start":936},[1106,1855,1856,1859],{},[1109,1857,1858],{},"\"blob\"",": 表示响应的数据类型是 Blob 对象，适用于文件下载等场景。",[1212,1861,1864],{"className":1862,"code":1863,"language":1217,"meta":1218},[1215],"xhr.responseType = \"blob\";\n",[1147,1865,1863],{"__ignoreMap":1218},[1096,1867,1868,1869,1871,1872,1874,1875,1877],{},"通过设置不同的 ",[1147,1870,1772],{}," 值，可以根据需要获取不同类型的响应数据。注意，在设置 ",[1147,1873,1772],{}," 之前，最好在调用 ",[1147,1876,1306],{}," 方法之后、发送请求之前设置，以确保设置生效。",[1137,1879,1117],{"id":1880},"ajax",[1096,1882,1883],{},"AJAX（Asynchronous JavaScript and XML，异步 JavaScript 和 XML）是一种使用现有的网页技术来创建异步请求和更新页面内容的方法。Ajax 本身不是一种技术，而是一种将一些现有技术结合起来使用的方法，包括：HTML 或 XHTML、CSS、JavaScript、DOM、XML、XSLT、以及最重要的 XMLHttpRequest 对象。",[1096,1885,1886],{},"当使用结合了这些技术的 Ajax 模型以后，网页应用能够快速地将增量更新呈现在用户界面上，而不需要重载（刷新）整个页面。这使得程序能够更快地回应用户的操作。Ajax 最吸引人的特性是它的\"异步\"性质，这意味着它可以与服务器通信、交换数据并更新页面，而无需刷新页面。",[1096,1888,1889,1890],{},"Ajax 是一种使用浏览器提供的 XMLHttpRequest 对象实现的技术，用于在不刷新整个页面的情况下进行异步请求和更新页面内容。",[1109,1891,1892],{},"可以说 Ajax 是基于浏览器提供的 XMLHttpRequest 对象来实现的。",[1096,1894,1895],{},"以下是基于原生 JavaScript 的 AJAX 请求代码示例：",[1212,1897,1900],{"className":1898,"code":1899,"language":1217,"meta":1218},[1215],"\u002F\u002F 创建 XMLHttpRequest 对象\nconst xhr = new XMLHttpRequest();\n\n\u002F\u002F 指定请求的方法和 URL\nxhr.open(\"GET\", \"api_url\", true); \u002F\u002F 第三个参数 true 表示异步请求\n\n\u002F\u002F 设置请求头（如果需要）\nxhr.setRequestHeader(\"Content-Type\", \"application\u002Fjson\"); \u002F\u002F 根据实际需求设置请求头\n\n\u002F\u002F 注册一个回调函数来处理响应\nxhr.onreadystatechange = function () {\n    if (xhr.readyState === 4 && xhr.status === 200) {\n        const response = JSON.parse(xhr.responseText); \u002F\u002F 处理响应数据\n        \u002F\u002F 在这里执行相应的操作\n        console.log(response);\n    }\n};\n\n\u002F\u002F 发送请求\nxhr.send();\n",[1147,1901,1899],{"__ignoreMap":1218},[1096,1903,1904],{},"虽然 AJAX 是一种强大的技术，但相对于 Axios 和 Fetch API，它有以下一些缺点：",[1103,1906,1907,1913,1919,1925,1930],{},[1106,1908,1909,1912],{},[1109,1910,1911],{},"兼容性问题","：AJAX 的兼容性相对较低，尤其在旧版本的浏览器中可能会出现问题。而 Axios 和 Fetch API 使用了更现代的 JavaScript 特性，具有更好的兼容性。",[1106,1914,1915,1918],{},[1109,1916,1917],{},"代码冗余","：使用原生的 AJAX 需要编写较多的代码来处理不同的状态码、错误处理以及请求的拼装等。而 Axios 和 Fetch API 提供了更简洁和易用的接口，减少了代码冗余。",[1106,1920,1921,1924],{},[1109,1922,1923],{},"缺乏默认配置","：AJAX 不提供默认的全局配置，如请求和响应拦截器、统一的错误处理等。而 Axios 和 Fetch API 支持全局配置，并且提供了更方便的拦截器机制。",[1106,1926,1927,1929],{},[1109,1928,1170],{},"：AJAX 在处理跨域请求时需要注意添加额外的处理，比如设置 CORS 头部信息或者使用 JSONP。而 Axios 和 Fetch API 提供了更直接的方式来处理跨域请求。",[1106,1931,1932,1935],{},[1109,1933,1934],{},"可读性较差","：由于 AJAX 使用的是回调函数来处理异步请求，可能会导致代码逻辑比较复杂，可读性较差。而 Axios 和 Fetch API 使用的是 Promise 或 async\u002Fawait，使代码结构更加清晰易读。",[1134,1937],{},[1134,1939],{},[1137,1941,1123],{"id":1942},"fetch",[1096,1944,1945],{},"Fetch 是一种用于进行网络请求的现代 JavaScript API。它提供了一种简单、灵活且功能强大的方式，用于从服务器获取资源并处理响应。",[1096,1947,1948],{},"Fetch API 在浏览器中原生支持，并且以 Promise 为基础，使得异步请求更加直观和易用。使用 Fetch API，可以执行各种类型的请求（如 GET、POST、PUT、DELETE 等），发送请求时可以设置请求头、请求参数，以及处理响应数据。",[1096,1950,1951],{},"与传统的 AJAX 相比，Fetch API 具有以下优点：",[1103,1953,1954,1960,1966,1972],{},[1106,1955,1956,1959],{},[1109,1957,1958],{},"Promise 支持","：Fetch API 使用 Promise 对象来处理异步操作，使得处理异步请求的流程更加清晰、易于阅读和编写。",[1106,1961,1962,1965],{},[1109,1963,1964],{},"更简洁的 API","：Fetch API 提供了一个简洁的 API，使发送请求变得更加直观和简单，同时提供了丰富的配置选项（如设置请求头、请求参数等）。",[1106,1967,1968,1971],{},[1109,1969,1970],{},"内置的 JSON 解析","：在处理响应时，Fetch API 内置了对 JSON 数据的解析，无需手动进行解析操作。",[1106,1973,1974,1977],{},[1109,1975,1976],{},"更好的错误处理","：Fetch API 使用了更全面的错误处理机制，允许通过检查响应状态码来确定请求是否成功，并以不同的方式处理错误。",[1195,1979,1981],{"id":1980},"fetch-1","fetch()",[1096,1983,1984,1985,1987],{},"Fetch API 提供了一个全局的 ",[1147,1986,1981],{}," 方法，该方法提供了一种简单、逻辑的方式来通过网络异步获取资源。",[1096,1989,1990,1992],{},[1147,1991,1981],{}," 方法的语法如下：",[1212,1994,1997],{"className":1995,"code":1996,"language":1217,"meta":1218},[1215],"fetch(url, options)\n    .then((response) => {\n        \u002F\u002F 在这里处理响应\n    })\n    .catch((error) => {\n        \u002F\u002F 在这里处理错误\n    });\n",[1147,1998,1996],{"__ignoreMap":1218},[1096,2000,2001],{},"这里有两个参数：",[1103,2003,2004,2009],{},[1106,2005,2006,2008],{},[1147,2007,1335],{},"：请求的 URL 地址。",[1106,2010,2011,2014],{},[1147,2012,2013],{},"options","（可选）：一个包含请求选项的对象，可以指定请求的方法（method）、请求头（headers）、请求体（body）等。",[1096,2016,2017,2018,2020,2021,2023],{},"注意，",[1147,2019,1981],{},"默认使用的是 GET 请求，如果需要使用其他方法（如 POST、PUT 等），需要通过 ",[1147,2022,2013],{}," 参数进行设置。",[1096,2025,2026,2028,2029,2032,2033,2036],{},[1147,2027,1981],{}," 方法返回一个 Promise 对象，可以使用 ",[1147,2030,2031],{},".then()"," 方法来处理成功的响应，使用 ",[1147,2034,2035],{},".catch()"," 方法来处理错误的情况。",[1103,2038,2039,2049],{},[1106,2040,2041,2042,2044,2045,2048],{},"在 ",[1147,2043,2031],{}," 中，可以访问到 ",[1147,2046,2047],{},"response"," 对象，进一步处理响应的内容。",[1106,2050,2041,2051,2053,2054,2057],{},[1147,2052,2035],{}," 中，我们可以访问到 ",[1147,2055,2056],{},"error"," 对象，用于处理请求过程中的任何错误。",[1096,2059,2060,2062],{},[1147,2061,2013],{}," 对象包含的属性如下：",[1212,2064,2067],{"className":2065,"code":2066,"language":1217,"meta":1218},[1215],"{\n  method: 'POST', \u002F\u002F *GET, POST, PUT, DELETE等\n  mode: 'cors', \u002F\u002F no-cors, *cors, same-origin\n  cache: 'no-cache', \u002F\u002F *default, no-cache, reload, force-cache, only-if-cached\n  credentials: 'same-origin', \u002F\u002F include, *same-origin, omit\n  headers: {\n    'Content-Type': 'application\u002Fjson'\n  },\n  redirect: 'follow', \u002F\u002F manual, *follow, error\n  referrerPolicy: 'no-referrer', \u002F\u002F no-referrer, *client\n  body: JSON.stringify(data)\n   \u002F\u002F body 数据类型必须与 \"Content-Type\" 请求头匹配\n}\n",[1147,2068,2066],{"__ignoreMap":1218},[1103,2070,2071,2076,2082,2088,2094,2099,2105,2111],{},[1106,2072,2073,2075],{},[1147,2074,1322],{},"：请求方法，例如 GET、POST、PUT、DELETE 等。",[1106,2077,2078,2081],{},[1147,2079,2080],{},"mode","：请求模式，可以是 no-cors、*cors、same-origin 等。",[1106,2083,2084,2087],{},[1147,2085,2086],{},"cache","：缓存模式，可以是 default、no-cache、reload、force-cache、only-if-cached 等。",[1106,2089,2090,2093],{},[1147,2091,2092],{},"credentials","：请求的凭证模式，可以是 include、*same-origin、omit 等。",[1106,2095,2096,2098],{},[1147,2097,1483],{},"：请求头对象，用于设置请求头的键值对。",[1106,2100,2101,2104],{},[1147,2102,2103],{},"redirect","：重定向模式，可以是 manual、*follow、error 等。",[1106,2106,2107,2110],{},[1147,2108,2109],{},"referrerPolicy","：引用页面隐私设置，可以是 no-referrer、*client 等。",[1106,2112,2113,2116,2117,2120],{},[1147,2114,2115],{},"body","：请求体数据，必须与 \"Content-Type\" 请求头指定的数据类型匹配。在示例中，使用",[1147,2118,2119],{},"JSON.stringify()","将数据转换为 JSON 字符串。",[1195,2122,2047],{"id":2047},[1096,2124,2125],{},"一旦获取到响应（Response），返回的对象包含以下属性：",[1103,2127,2128,2134,2140,2146,2152,2158,2164,2170,2176],{},[1106,2129,2130,2133],{},[1147,2131,2132],{},"response.body","：一个简单的 getter，提供了响应内容的可读流（ReadableStream）。",[1106,2135,2136,2139],{},[1147,2137,2138],{},"response.bodyUsed","：一个布尔值，用于记录响应体是否已经被使用过。",[1106,2141,2142,2145],{},[1147,2143,2144],{},"response.headers","：与响应相关联的头部信息对象。",[1106,2147,2148,2151],{},[1147,2149,2150],{},"response.ok","：一个布尔值，指示响应是否成功。",[1106,2153,2154,2157],{},[1147,2155,2156],{},"response.redirected","：指示响应是否是重定向结果的布尔值。",[1106,2159,2160,2163],{},[1147,2161,2162],{},"response.status","：响应的状态码。",[1106,2165,2166,2169],{},[1147,2167,2168],{},"response.statusText","：与状态码对应的状态消息。",[1106,2171,2172,2175],{},[1147,2173,2174],{},"response.type","：响应的类型。",[1106,2177,2178,2181],{},[1147,2179,2180],{},"response.url","：响应的 URL。",[1096,2183,2184,2185,2187],{},"我们可以使用 ",[1147,2186,2174],{}," 来确定响应的类型，并根据不同的类型采取相应的处理方法：",[1212,2189,2192],{"className":2190,"code":2191,"language":1217,"meta":1218},[1215],"fetch(url)\n    .then((response) => {\n        \u002F\u002F 检查响应状态码\n        if (!response.ok) {\n            throw new Error(\"Network response was not ok\");\n        }\n        \u002F\u002F 定义一个响应类型与解析方法的映射关系\n        const responseTypes = new Map([\n            [\"json\", () => response.json()],\n            [\"text\", () => response.text()],\n            [\"formData\", () => response.formData()],\n            [\"blob\", () => response.blob()],\n            [\"arrayBuffer\", () => response.arrayBuffer()],\n        ]);\n        \u002F\u002F 根据响应类型选择相应的解析方法\n        const parser = responseTypes.get(response.type);\n        if (parser) {\n            return parser();\n        } else {\n            throw new Error(\"Unsupported response type\");\n        }\n    })\n    .then((data) => {\n        \u002F\u002F 处理数据\n        console.log(data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误情况\n        console.error(\"Error:\", error);\n    });\n",[1147,2193,2191],{"__ignoreMap":1218},[1096,2195,2196,2199],{},[1147,2197,2198],{},"Response"," 对象提供了 5 个方法，用于从 HTTP 响应中获取不同类型的数据：",[1103,2201,2202,2212,2218,2224,2230],{},[1106,2203,2204,2207,2208,2211],{},[1147,2205,2206],{},"response.json()","：将响应体解析为 JSON 对象。如果响应的 Content-Type 是 ",[1147,2209,2210],{},"application\u002Fjson","，则使用此方法。",[1106,2213,2214,2217],{},[1147,2215,2216],{},"response.text()","：将响应体解析为文本字符串。如果响应的 Content-Type 是纯文本类型，如 text\u002Fplain 或 text\u002Fhtml，则使用此方法。",[1106,2219,2220,2223],{},[1147,2221,2222],{},"response.formData()","：将响应体解析为 FormData 对象。如果响应的 Content-Type 是 multipart\u002Fform-data，则使用此方法。FormData 通常用于上传文件或提交表单数据。",[1106,2225,2226,2229],{},[1147,2227,2228],{},"response.blob()","：将响应体解析为 Blob 对象。Blob 对象表示二进制大对象，可以是图像、音频、视频等类型的数据。",[1106,2231,2232,2235],{},[1147,2233,2234],{},"response.arrayBuffer()","：将响应体解析为 ArrayBuffer 对象。ArrayBuffer 是一种表示二进制数据的固定长度缓冲区。",[1096,2237,2238],{},"这些方法返回一个 Promise，当解析完成时，Promise 将被解析为相应的数据类型。",[1195,2240,1405],{"id":2241},"请求头和响应头-1",[1096,2243,2244,2245,2247],{},"fetch 函数的请求头包含在发起 HTTP 请求时发送给服务器的信息，用于传递额外的参数和配置。可以使用 ",[1147,2246,1483],{}," 对象来设置和操作请求头。常见的请求头字段包括：",[1103,2249,2250,2262,2267,2273],{},[1106,2251,2252,2254,2255,2257,2258,2261],{},[1147,2253,1427],{},"：指定请求体的格式类型，如 ",[1147,2256,2210],{},"、",[1147,2259,2260],{},"application\u002Fx-www-form-urlencoded"," 等。",[1106,2263,2264,2266],{},[1147,2265,1430],{},"：用于身份验证，通常与 Token 或用户名密码一起使用。",[1106,2268,2269,2272],{},[1147,2270,2271],{},"Accept","：指定客户端所能接受的响应数据类型。",[1106,2274,2275,2278],{},[1147,2276,2277],{},"User-Agent","：标识发起请求的用户代理（浏览器或应用程序）的信息。",[1096,2280,2281],{},"在 fetch 函数中可以通过第二个参数进行配置，其中可以指定请求头：",[1212,2283,2286],{"className":2284,"code":2285,"language":1217,"meta":1218},[1215],"fetch(url, {\n    method: \"GET\",\n    headers: {\n        \"Content-Type\": \"application\u002Fjson\",\n        Authorization: \"Bearer token123\",\n    },\n})\n    .then((response) => {\n        \u002F\u002F 处理响应\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n    });\n",[1147,2287,2285],{"__ignoreMap":1218},[1096,2289,2290,2291,2293,2294,2296],{},"响应头是服务器在响应 HTTP 请求时发送给客户端的头部信息。可以通过 ",[1147,2292,2198],{}," 对象的 ",[1147,2295,1483],{}," 属性访问响应头。常见的响应头字段包括：",[1103,2298,2299,2304,2310,2316],{},[1106,2300,2301,2303],{},[1147,2302,1427],{},"：指定响应体的格式类型。",[1106,2305,2306,2309],{},[1147,2307,2308],{},"Set-Cookie","：设置或修改客户端的 Cookie。",[1106,2311,2312,2315],{},[1147,2313,2314],{},"Cache-Control","：控制缓存的行为，如 no-cache、max-age 等。",[1106,2317,2318,2321],{},[1147,2319,2320],{},"Content-Disposition","：指定响应的内容该如何展示（如文件的下载）。",[1096,2323,2324,2325,2327,2328,2330,2331,2334],{},"在处理 ",[1147,2326,1942],{}," 返回的 ",[1147,2329,2198],{}," 对象时，可以通过调用 ",[1147,2332,2333],{},"response.headers.get('Header-Name')"," 方法来获取特定的响应头字段的值。",[1212,2336,2339],{"className":2337,"code":2338,"language":1217,"meta":1218},[1215],"fetch(url)\n    .then((response) => {\n        const contentType = response.headers.get(\"Content-Type\");\n        \u002F\u002F 其他处理逻辑\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n    });\n",[1147,2340,2338],{"__ignoreMap":1218},[1195,2342,1186],{"id":1186},[1096,2344,2345,2346,2349],{},"除了可以使用 catch() 来处理错误之外，与使用其他异步操作一样，我们也可以使用 ",[1147,2347,2348],{},"async\u002Fawait"," 来处理异步请求，使代码更加简洁和易读：",[1212,2351,2354],{"className":2352,"code":2353,"language":1217,"meta":1218},[1215],"async function fetchData() {\n    try {\n        const response = await fetch(\"https:\u002F\u002Fapi.example.com\u002Fdata\");\n        if (response.ok) {\n            const data = await response.json();\n            console.log(data); \u002F\u002F 处理解析后的数据\n        } else {\n            throw new Error(\"请求失败\");\n        }\n    } catch (error) {\n        console.log(error); \u002F\u002F 处理错误\n    }\n}\n\nfetchData();\n",[1147,2355,2353],{"__ignoreMap":1218},[1195,2357,2358],{"id":2358},"取消请求",[1096,2360,2361],{},"在标准的 Fetch API 中，没有提供直接取消 Fetch 请求的内置方法。但是，可以使用以下方法来模拟或实现取消 Fetch 请求的效果。",[1096,2363,2364,2365,1150,2368,2371,2372,2374,2375,2377,2378,2381],{},"使用 ",[1147,2366,2367],{},"AbortController",[1147,2369,2370],{},"AbortSignal","：这是一种较新的浏览器特性，用于生成可以取消请求的信号。可以创建一个 ",[1147,2373,2367],{},"对象，然后将其关联到 Fetch 请求中，当需要取消请求时，调用 ",[1147,2376,2367],{}," 的 ",[1147,2379,2380],{},"abort()","方法：",[1212,2383,2386],{"className":2384,"code":2385,"language":1217,"meta":1218},[1215],"\u002F\u002F 创建 AbortController 和关联的 signal\nconst abortController = new AbortController();\nconst signal = abortController.signal;\n\n\u002F\u002F 发起 Fetch 请求，并将 signal 传递给 fetch 函数\nfetch(url, { signal })\n    .then((response) => {\n        \u002F\u002F 处理响应\n    })\n    .catch((error) => {\n        if (error.name === \"AbortError\") {\n            \u002F\u002F 请求已被取消\n        } else {\n            \u002F\u002F 处理其他错误\n        }\n    });\n\n\u002F\u002F 当需要取消请求时，调用 abort() 方法\nabortController.abort();\n",[1147,2387,2385],{"__ignoreMap":1218},[1137,2389,207],{"id":2390},"axios",[1096,2392,2393,2394,2397,2398,2401],{},"Axios 是一个基于 Promise 网络请求库，用于在浏览器和 Node.js 中进行 HTTP 请求。在服务端它使用原生 node.js ",[1147,2395,2396],{},"http"," 模块, 而在客户端 (浏览端) 则使用 ",[1147,2399,2400],{},"XMLHttpRequests","。Axios 是目前最流行的 HTTP 请求库，其 npm 每周下载量达到了 4500w+。",[1096,2403,2404],{},"Axios 库具有以下特点：",[1103,2406,2407,2413,2419,2425,2430,2436,2442,2448],{},[1106,2408,2409,2412],{},[1109,2410,2411],{},"浏览器和 Node.js","：Axios 可在浏览器和 Node.js 环境中使用，可以在不同的平台上执行 HTTP 请求。",[1106,2414,2415,2418],{},[1109,2416,2417],{},"Promise API","：Axios 使用 Promise API 进行异步操作，能够更轻松地处理异步请求和响应。",[1106,2420,2421,2424],{},[1109,2422,2423],{},"请求拦截和响应拦截","：可以通过拦截器，在请求发送之前或响应返回之后对请求进行全局性或个性化的变换和处理。可以在请求或响应的不同阶段添加公共的请求头、验证身份、处理错误等。",[1106,2426,2427,2429],{},[1109,2428,2358],{},"：Axios 允许取消未完成的请求，以避免无效的请求，并减轻服务器的负担。取消请求可以通过创建取消令牌、使用取消令牌进行请求配置或者在拦截器中中断请求来实现。",[1106,2431,2432,2435],{},[1109,2433,2434],{},"并发请求","：Axios 提供了执行多个并发请求的能力，可以同时发起多个请求，并在所有请求完成后进行处理。",[1106,2437,2438,2441],{},[1109,2439,2440],{},"自动转换数据","：Axios 可以自动将请求和响应的数据进行格式转换，包括 JSON、URL 编码等。无需手动处理数据转换的过程。",[1106,2443,2444,2447],{},[1109,2445,2446],{},"错误处理机制","：当请求过程中出现错误时，Axios 会返回详细的错误信息，包括 HTTP 错误状态码、错误描述等。可以根据需要对这些错误进行处理和显示。",[1106,2449,2450,2453],{},[1109,2451,2452],{},"简洁的 API","：Axios 的 API 设计简洁易用，具有直观的方法命名和参数配置。可以轻松地使用 Axios 进行 GET、POST、PUT、DELETE 等常见的 HTTP 请求。",[1096,2455,2456],{},"可以通过以下命令来安装 Axios：",[1212,2458,2463],{"className":2459,"code":2461,"language":2462,"meta":1218},[2460],"language-bash","\u002F\u002F 使用 npm 安装\nnpm install axios\n\n\u002F\u002F 使用 yarn 安装\nyarn add axios\n","bash",[1147,2464,2461],{"__ignoreMap":1218},[1096,2466,2467],{},"下面来进行一个简单的 get 请求：",[1212,2469,2472],{"className":2470,"code":2471,"language":1217,"meta":1218},[1215],"axios\n    .get(\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n        console.error(error);\n    });\n",[1147,2473,2471],{"__ignoreMap":1218},[1096,2475,1421,2476,2479,2480,2483,2484,2487,2488,2491],{},[1147,2477,2478],{},"axios.get"," 方法发起了一个 GET 请求，并将请求的 URL 作为参数传递给该方法。然后使用 Promise 的 ",[1147,2481,2482],{},".then"," 方法处理成功响应，并通过 ",[1147,2485,2486],{},"response.data"," 获取响应数据。如果请求失败，可以通过 Promise 的 ",[1147,2489,2490],{},".catch"," 方法捕获错误。",[1195,2493,2494],{"id":2494},"请求方法",[1096,2496,2497],{},"axios 支持通过简写方式来执行不同类型的请求：",[1103,2499,2500,2503,2511,2516,2521,2526,2534,2541],{},[1106,2501,2502],{},"axios.request(config)",[1106,2504,2505,2506,2510],{},"axios.get(url",[2507,2508,2509],"span",{},", config",")",[1106,2512,2513,2514,2510],{},"axios.delete(url",[2507,2515,2509],{},[1106,2517,2518,2519,2510],{},"axios.head(url",[2507,2520,2509],{},[1106,2522,2523,2524,2510],{},"axios.options(url",[2507,2525,2509],{},[1106,2527,2528,2529,2510],{},"axios.post(url",[2507,2530,2531,2532],{},", data",[2507,2533,2509],{},[1106,2535,2536,2537,2510],{},"axios.put(url",[2507,2538,2531,2539],{},[2507,2540,2509],{},[1106,2542,2543,2544,2510],{},"axios.patch(url",[2507,2545,2531,2546],{},[2507,2547,2509],{},[1096,2549,2550],{},"对于这些方法，第一个参数是请求的 URL，config 和 data 分别是请求的配置项和请求参数，这两个参数都是可选的。例如，下面是一个 post 请求：",[1212,2552,2555],{"className":2553,"code":2554,"language":1217,"meta":1218},[1215],"const options = {\n    headers: { \"X-Custom-Header\": \"value\" },\n};\n\naxios\n    .post(\"\u002Fsave\", { a: 10 }, options)\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n        console.error(error);\n    });\n",[1147,2556,2554],{"__ignoreMap":1218},[1096,2558,2559,2560,2563,2564,2566,2567],{},"当作为第二个参数传递给 ",[1147,2561,2562],{},"axios.post"," 函数时，Axios 会自动将 JavaScript 对象序列化为 JSON。 这样就无需将 POST 正文序列化为 JSON。Axios 还会自动将 ",[1147,2565,1427],{}," 请求头设置为 ",[1147,2568,2210],{},[1195,2570,2571],{"id":2571},"多个请求",[1096,2573,2574,2575,1150,2578,2581],{},"在 Axios 中，可以使用 ",[1147,2576,2577],{},"axios.all",[1147,2579,2580],{},"axios.spread"," 来处理多个并发的请求：",[1212,2583,2586],{"className":2584,"code":2585,"language":1217,"meta":1218},[1215],"const axios = require(\"axios\");\n\n\u002F\u002F 创建多个请求\nconst request1 = axios.get(\"https:\u002F\u002Fapi.example.com\u002Fdata1\");\nconst request2 = axios.get(\"https:\u002F\u002Fapi.example.com\u002Fdata2\");\n\n\u002F\u002F 并发发送多个请求\naxios\n    .all([request1, request2])\n    .then(\n        axios.spread((response1, response2) => {\n            \u002F\u002F 处理各个请求的响应\n            console.log(response1.data);\n            console.log(response2.data);\n        }),\n    )\n    .catch((error) => {\n        \u002F\u002F 处理错误\n        console.error(error);\n    });\n",[1147,2587,2585],{"__ignoreMap":1218},[1096,2589,2590,2591,2593,2594,2596,2597,2600,2601,2604],{},"可以看到，在 ",[1147,2592,2482],{}," 方法中使用了 ",[1147,2595,2580],{}," 函数将多个请求的响应结果进行解构，通过多个参数分别接收各个请求的响应。可以根据实际情况命名这些参数，并通过 ",[1147,2598,2599],{},"response1.data","、r",[1147,2602,2603],{},"esponse2.data"," 等方式获取各个请求的响应数据。",[1195,2606,2608],{"id":2607},"请求拦截响应拦截","请求拦截、响应拦截",[1096,2610,2574,2611,2614],{},[1147,2612,2613],{},"transformRequest"," 方法在请求发送之前对请求数据进行转换和处理，它是一个请求拦截器，是一个可选的函数。",[1096,2616,2617,2618,2621,2622,1150,2625,2628,2629,2631,2632,2634,2635,2637],{},"tran",[1147,2619,2620],{},"sformRequest"," 函数接收两个参数：",[1147,2623,2624],{},"requestData",[1147,2626,2627],{},"requestHeaders","。其中，",[1147,2630,2624],{}," 是要发送的请求数据，",[1147,2633,2627],{}," 是要发送的请求头信息。可以在 ",[1147,2636,2613],{}," 函数内部对这些参数进行修改，并将修改后的值返回。返回的结果将作为实际发送请求的数据。",[1212,2639,2642],{"className":2640,"code":2641,"language":1217,"meta":1218},[1215],"axios({\n    url: \"https:\u002F\u002Fapi.example.com\u002Fdata\",\n    method: \"post\",\n    data: {\n        id: 12345,\n        name: \"John Doe\",\n    },\n    transformRequest: (data, headers) => {\n        \u002F\u002F 对请求数据进行转换和处理\n        const modifiedData = { ...data }; \u002F\u002F 复制原始数据\n\n        \u002F\u002F 修改数据或添加额外字段\n        modifiedData.extraField = \"Extra Value\";\n\n        \u002F\u002F 修改请求头信息\n        headers[\"Content-Type\"] = \"application\u002Fjson\";\n\n        return JSON.stringify(modifiedData); \u002F\u002F 返回处理后的数据\n    },\n})\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n        console.error(error);\n    });\n",[1147,2643,2641],{"__ignoreMap":1218},[1096,2645,2646,2647,2649,2650,2652,2653,2656,2657,2659],{},"这里使用 Axios 发起了一个 POST 请求。通过传递包含 ",[1147,2648,2613],{}," 函数的配置对象来定义请求。在 ",[1147,2651,2613],{}," 函数内部，复制了原始的请求数据 ",[1147,2654,2655],{},"data","，并进行了一些修改和处理，如添加了额外的字段和修改了请求头信息。最终，将修改后的数据以 JSON 字符串的形式返回。Axios 将使用 ",[1147,2658,2613],{}," 函数返回的结果作为实际发送请求的数据。",[1096,2661,2662,2663,2666,2667,2670,2671,2673],{},"除了可以对请求进行拦截之外，Axios 还支持对响应进行拦截，对响应数据进行转换和处理。可以通过 ",[1147,2664,2665],{},"transformResponse"," 响应拦截器来实现。该函数接收一个参数：",[1147,2668,2669],{},"responseData","，它是从服务器接收到的原始响应数据。可以在 ",[1147,2672,2665],{}," 函数内部对这个参数进行修改，并将修改后的值返回。返回的结果将作为实际处理响应的数据。",[1212,2675,2678],{"className":2676,"code":2677,"language":1217,"meta":1218},[1215],"axios\n    .get(\"https:\u002F\u002Fapi.example.com\u002Fdata\", {\n        transformResponse: (data) => {\n            \u002F\u002F 对响应数据进行转换和处理\n            const parsedData = JSON.parse(data); \u002F\u002F 解析 JSON 字符串\n\n            \u002F\u002F 修改数据或添加额外字段\n            parsedData.extraField = \"Extra Value\";\n\n            return parsedData; \u002F\u002F 返回处理后的数据\n        },\n    })\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理错误\n        console.error(error);\n    });\n",[1147,2679,2677],{"__ignoreMap":1218},[1096,2681,2682,2683,2649,2685,2687,2688,2690],{},"这里使用 Axios 发起了一个 GET 请求，并通过传递包含 ",[1147,2684,2665],{},[1147,2686,2665],{}," 函数内部，对从服务器接收到的响应数据 ",[1147,2689,2655],{}," 进行了一些修改和处理，如解析 JSON 字符串，添加了额外的字段。最终将修改后的数据返回。",[1195,2692,2693],{"id":2693},"拦截请求和响应",[1096,2695,2696,2697,2700],{},"Axios 中，可以使用拦截器来拦截请求和响应，并在其被发送或接收之前进行一些额外的处理，可以通过 ",[1147,2698,2699],{},"axios.interceptors"," 对象来添加拦截器。",[1212,2702,2705],{"className":2703,"code":2704,"language":1217,"meta":1218},[1215],"\u002F\u002F 添加请求拦截器\naxios.interceptors.request.use(\n    (config) => {\n        \u002F\u002F 在发送请求之前做一些处理\n        console.log(\"请求拦截器\");\n\n        \u002F\u002F 修改请求配置\n        config.headers[\"Authorization\"] = \"Bearer token\";\n\n        return config;\n    },\n    (error) => {\n        \u002F\u002F 处理请求错误\n        console.error(\"请求出错：\", error);\n    },\n);\n\n\u002F\u002F 添加响应拦截器\naxios.interceptors.response.use(\n    (response) => {\n        \u002F\u002F 在接收到响应数据之前做一些处理\n        console.log(\"响应拦截器\");\n\n        \u002F\u002F 修改响应数据\n        response.data = { ...response.data, extraField: \"Extra Value\" };\n\n        return response;\n    },\n    (error) => {\n        \u002F\u002F 处理响应错误\n        console.error(\"响应出错：\", error);\n    },\n);\n\n\u002F\u002F 发送请求\naxios\n    .get(\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理请求或响应错误\n        console.error(error);\n    });\n",[1147,2706,2704],{"__ignoreMap":1218},[1096,2708,2709,2710,2713,2714,2717],{},"这里首先使用 ",[1147,2711,2712],{},"axios.interceptors.request.use"," 方法添加了一个请求拦截器。该拦截器在发送请求之前被调用，并接收请求配置对象 ",[1147,2715,2716],{},"config"," 作为参数。可以对请求配置进行修改，如添加请求头信息。最后，要确保返回修改后的配置对象。",[1096,2719,2720,2721,2724,2725,2727],{},"接下来，使用 ",[1147,2722,2723],{},"axios.interceptors.response.use"," 方法添加了一个响应拦截器。该拦截器在接收到响应数据之前被调用，并接收响应对象 ",[1147,2726,2047],{}," 作为参数。可以对响应数据进行修改，如添加额外的字段。同样，要确保返回修改后的响应对象。",[1195,2729,2731],{"id":2730},"客户端支持-xsrf-防护","客户端支持 XSRF 防护",[1096,2733,2734,2735,2737],{},"跨站请求伪造（简称 XSRF）是一种攻击 Web 应用的方法，其中攻击者将自己伪装成合法且受信任的用户，以影响应用程序与用户浏览器之间的交互。 有很多方法可以执行此类攻击，包括 ",[1147,2736,1209],{},"。",[1096,2739,2740],{},"幸运的是，Axios 通过允许在发出请求时嵌入额外的身份验证数据来防止 XSRF。 这使得服务器能够发现来自未经授权的位置的请求。以下是使用 Axios 完成此操作的方法：",[1212,2742,2745],{"className":2743,"code":2744,"language":1217,"meta":1218},[1215],"const options = {\n    method: \"post\",\n    url: \"\u002Flogin\",\n    xsrfCookieName: \"XSRF-TOKEN\",\n    xsrfHeaderName: \"X-XSRF-TOKEN\",\n};\n\naxios(options)\n    .then((response) => {\n        \u002F\u002F 处理成功响应\n        console.log(response.data);\n    })\n    .catch((error) => {\n        \u002F\u002F 处理请求错误\n        console.error(error);\n    });\n",[1147,2746,2744],{"__ignoreMap":1218},[1096,2748,2749],{},"这里有两个 xsrf 相关的属性：",[1103,2751,2752,2758],{},[1106,2753,2754,2757],{},[1147,2755,2756],{},"xsrfCookieName: 'XSRF-TOKEN'","：用于跨站请求伪造(XSRF\u002FCSRF)保护的配置选项之一。它指定了存储 XSRF 令牌的 cookie 的名称。XSRF 令牌用于防止恶意网站发起对已验证用户的请求。",[1106,2759,2760,2763],{},[1147,2761,2762],{},"xsrfHeaderName: 'X-XSRF-TOKEN'","：用于跨站请求伪造(XSRF\u002FCSRF)保护的配置选项之一。它指定了包含 XSRF 令牌的请求头的名称。服务器端可以通过检查该请求头来验证请求的合法性。",[1195,2765,2766],{"id":2766},"请求进度",[1096,2768,2769,2770,1150,2773,2776],{},"Axios 的另一个有趣的功能是能够监控请求的进度，这在下载或上传大文件时特别有用，可以使用 ",[1147,2771,2772],{},"onUploadProgress",[1147,2774,2775],{},"onDownloadProgress"," 两个配置选项来实现。",[1096,2778,2779,2780,2782],{},"对于上传进度，可以使用 ",[1147,2781,2772],{}," 配置选项。它会在上传数据时触发，并提供关于上传进度的信息。",[1212,2784,2787],{"className":2785,"code":2786,"language":1217,"meta":1218},[1215],"axios\n    .post(\"\u002Fupload\", data, {\n        onUploadProgress: (progressEvent) => {\n            const percentCompleted = Math.round(\n                (progressEvent.loaded * 100) \u002F progressEvent.total,\n            );\n            console.log(`上传进度：${percentCompleted}%`);\n        },\n    })\n    .then((response) => {\n        console.log(response.data);\n    })\n    .catch((error) => {\n        console.error(error);\n    });\n",[1147,2788,2786],{"__ignoreMap":1218},[1096,2790,2791,2792,2794],{},"这里发送了一个 POST 请求，在配置选项中使用了 ",[1147,2793,2772],{},"。当数据上传过程中触发进度事件时，回调函数会被执行。在回调函数中，我们计算出了已上传数据的百分比，并将其打印出来。",[1096,2796,2797,2798,2800],{},"对于下载进度，可以使用 ",[1147,2799,2775],{}," 配置选项。它会在接收到响应数据时触发，并提供关于下载进度的信息。",[1212,2802,2805],{"className":2803,"code":2804,"language":1217,"meta":1218},[1215],"axios\n    .get(\"\u002Fdownload\", {\n        onDownloadProgress: (progressEvent) => {\n            const percentCompleted = Math.round(\n                (progressEvent.loaded * 100) \u002F progressEvent.total,\n            );\n            console.log(`下载进度：${percentCompleted}%`);\n        },\n    })\n    .then((response) => {\n        console.log(response.data);\n    })\n    .catch((error) => {\n        console.error(error);\n    });\n",[1147,2806,2804],{"__ignoreMap":1218},[1096,2808,2809,2810,2812],{},"这里发送了一个 GET 请求，在配置选项中使用了 ",[1147,2811,2775],{},"。当数据下载过程中触发进度事件时，回调函数会被执行。在回调函数中，我们计算出了已下载数据的百分比，并将其打印出来。",[1195,2814,2358],{"id":2815},"取消请求-1",[1096,2817,2818],{},"在 Axios 中，可以使用取消令牌（cancel token）来取消请求。取消令牌是一个对象，它表示一个具体的取消操作，并允许在需要时中止请求。",[1212,2820,2823],{"className":2821,"code":2822,"language":1217,"meta":1218},[1215],"\u002F\u002F 创建一个取消令牌源\nconst CancelToken = axios.CancelToken;\nconst source = CancelToken.source();\n\n\u002F\u002F 发送请求\naxios\n    .get(\"\u002Fapi\u002Fdata\", {\n        cancelToken: source.token,\n    })\n    .then((response) => {\n        console.log(response.data);\n    })\n    .catch((error) => {\n        if (axios.isCancel(error)) {\n            console.log(\"请求已被取消：\", error.message);\n        } else {\n            console.error(error);\n        }\n    });\n\n\u002F\u002F 取消请求\nsource.cancel(\"取消请求的原因\");\n",[1147,2824,2822],{"__ignoreMap":1218},[1096,2826,2827,2828,2831,2832,2835,2836,2839,2840,2843],{},"这里，先创建了一个取消令牌源 ",[1147,2829,2830],{},"source","。然后，发送 GET 请求时将 ",[1147,2833,2834],{},"cancelToken"," 配置选项设置为 ",[1147,2837,2838],{},"source.token","，即将取消令牌与该请求关联起来。当需要取消请求时，调用 ",[1147,2841,2842],{},"source.cancel()"," 方法，并传入取消请求的原因作为参数。",[1096,2845,2846,2847,2849,2850,2853],{},"在请求的 ",[1147,2848,2035],{}," 方法中，我们使用 ",[1147,2851,2852],{},"axios.isCancel(error)"," 来判断捕获的错误是否是一个已取消的请求。如果是取消请求导致的错误，则会打印出 '请求已被取消' 的提示信息。否则，将打印出其他类型的错误。",[1195,2855,2856],{"id":2856},"请求超时",[1096,2858,1408,2859,2862],{},[1147,2860,2861],{},"timeout"," 配置选项设置 Axios 请求的超时时间，这个选项指定了请求在多少毫秒后如果没有得到响应就会超时。",[1212,2864,2867],{"className":2865,"code":2866,"language":1217,"meta":1218},[1215],"axios\n    .get(\"\u002Fapi\u002Fdata\", {\n        timeout: 5000, \u002F\u002F 设置超时时间为5秒\n    })\n    .then((response) => {\n        console.log(response.data);\n    })\n    .catch((error) => {\n        console.error(error);\n    });\n",[1147,2868,2866],{"__ignoreMap":1218},[1096,2870,2871,2872,2874,2875,2877],{},"发送了一个 GET 请求，并在配置选项中设置了 ",[1147,2873,2861],{}," 为 5000 毫秒（即 5 秒）。如果请求在 5 秒内没有得到响应，就会触发超时错误。在超时错误的情况下，请求会被自动取消，并且进入 ",[1147,2876,2035],{}," 分支。您可以根据需要进行错误处理。",[1096,2879,2880,2881,2883],{},"注意，如果不设置 ",[1147,2882,2861],{}," 选项，默认情况下 Axios 请求是没有超时限制的。",[1134,2885],{},[1096,2887,2888],{},"相对于 Fetch、XMLHttpRequest 和 Ajax，还是更喜欢 Axios。主要是有简洁易用的 API，统一的错误处理和拦截器支持，取消请求和超时处理功能，以及基于 Promise 的链式调用和跨浏览器兼容， Axios 更方便、高效，并提供更好的开发体验",{"title":1218,"searchDepth":1247,"depth":1247,"links":2890},[2891,2900,2901,2908],{"id":1139,"depth":1223,"text":1111,"children":2892},[2893,2894,2895,2896,2897,2898,2899],{"id":1197,"depth":1235,"text":1197},{"id":1306,"depth":1235,"text":1306},{"id":1405,"depth":1235,"text":1405},{"id":1536,"depth":1235,"text":1294},{"id":1298,"depth":1235,"text":1298},{"id":1669,"depth":1235,"text":1669},{"id":1771,"depth":1235,"text":1772},{"id":1880,"depth":1223,"text":1117},{"id":1942,"depth":1223,"text":1123,"children":2902},[2903,2904,2905,2906,2907],{"id":1980,"depth":1235,"text":1981},{"id":2047,"depth":1235,"text":2047},{"id":2241,"depth":1235,"text":1405},{"id":1186,"depth":1235,"text":1186},{"id":2358,"depth":1235,"text":2358},{"id":2390,"depth":1223,"text":207,"children":2909},[2910,2911,2912,2913,2914,2915,2916,2917],{"id":2494,"depth":1235,"text":2494},{"id":2571,"depth":1235,"text":2571},{"id":2607,"depth":1235,"text":2608},{"id":2693,"depth":1235,"text":2693},{"id":2730,"depth":1235,"text":2731},{"id":2766,"depth":1235,"text":2766},{"id":2815,"depth":1235,"text":2358},{"id":2856,"depth":1235,"text":2856},"md",true,{"uuid":2921,"slots":2922},"a3988380-e3c1-11f0-ae2f-db43cc23fe97",{},26,{"title":1085,"description":1098},"posts\u002F2025\u002F2025-12-28-前端-关于网络请求（XHR、Ajax、Fetch、Axios）",[135,207],"6u6FyhvMDsOuotwjhQK2V-eZ_B0X2IB49xxGBxUepFI",1790443288131]