发送http请求的自定义函数库文件

📅 2026/7/5 14:46:59
发送http请求的自定义函数库文件
Fetch API 是现代浏览器提供的 JavaScript 网络请求接口‌用来替代老式的 XMLHttpRequest让前端发 HTTP 请求更简单高效。‌‌它不需要依赖任何外部的库操作起来简单又方便。从此发送异步请求再也不需要jQuery结合ajax了。自定义http-request-functions.js文件/* * 介绍通过fetch api实现原生javascript发送http异步请求。此js文件内定义了各种常用的http请求函数。 * 作者napster * 最后一次更新时间2026-07-04 */ /**** *pre * 介绍 * 发送键值对数据的http请求。发送请求时http协议报文内携带的内容为一个或多个键值对。 * * * * 注意 * Content-Type:application/x-www-form-urlencoded;charsetUTF-8 。 * * * * 参数 * url请求地址。 * * key_value_pair_object一个键值对对象即一个包含了任意个键值对数据的js对象。 * 例如 * const user { * username: zhangsan, * age: 16, * address: 北京 * }; * * * * 补充 * 调用方式 * ①使用async/await的调用方式 * 示例 * async function queryOneUser() { * try { * const result await kvpHttpRequest(/api/xxx, {id: 1}); * console.log(在外部拿到了返回的结果:, result); * } * catch(error) { * alert(error.message); * } * } * 解释 * 因为底层 fetch 发送的请求是异步的当代码执行 fetch(...) 时它是不会停下来等待服务器响应的而是直接往下走故整个函数在 fetch 还没拿到结果时就已经执行完毕了 * 所以调用时必须加上 await 进行等待才能得到最终的返回值。故调用时必须加上 await 关键字若在某个方法中使用 await 关键字则该方法必须加上 async 关键字。 * * ②使用Promise的链式调用.then().catch()方式 * 示例 * kvpHttpRequest(/api/xxx, {id: 1}) * .then(function(data) { * console.log(在外部拿到了返回的结果, data); * }) * .catch(function(error) { * alert(error.message); * }); */pre *****/ function kvpHttpRequest(url, key_value_pair_object) { /* * 检查空值 * ①null * ②undefined比如调用函数时压根没传第二个参数 * 检查类型 * 判断传入的参数是不是一个真正的“对象”。防止不小心传了一个数字、字符串、布尔值。 * 检查类型 * 判断传入的参数是不是一个数组由于数组本身也是对象所以要防止传入。 */ if (!key_value_pair_object || typeof key_value_pair_object ! object || Array.isArray(key_value_pair_object)) { const error new Error(方法参数值异常请传入有效的“键值对”对象); //创建一个错误对象 alert(error.message); //弹窗提示 throw error; //抛出 } console.log(准备发送请求); //1、创建一个用于封装请求参数的对象URLSearchParams const urlSearchParams new URLSearchParams(); //2、将键值对对象转换为二维数组后进行迭代然后把迭代出来的每一项都存入URLSearchParams对象中 /* * 通过Object.entries(...)可以将一个封装了键值对数据的js对象转换为一个包含“[key, value]”的二维数组其内部的每一项都是一个包含两个元素的数组。 * 例如 * 已知js对象 * const user { * username: zhangsan, * age: 16, * address: 北京 * }; * 转换后得到的二维数组 * [ * [username, zhangsan], * [age, 16], * [address, 北京] * ]; */ Object.entries(key_value_pair_object).forEach(function(item) { //得到的item是一个数组格式为 [key, value] const key item[0]; const value item[1]; urlSearchParams.append(key, value); }); //3、通过fetch发起请求。注意把fetch以及后续的.then()链条整体都return回去这样调用者才能得到返回的Promise对象 return fetch(url, { method: POST, body: urlSearchParams }) .then(function(response) { //fetch请求只有在断网时才会报错哪怕是服务器响应了404或500它依然会进入这里的.then()。 /* * response对象 * 介绍 * 该对象‌不是‌服务器直接传给前端的“原始业务数据如json对象或字符串”而是fetch api接口封装的一个http响应元数据对象‌即Response对象。 * 可以把它理解为一个“包裹”或“信封”它包含了关于这次网络请求的所有‌状态信息‌和‌头部信息‌而真正的“业务数据ResponseBody”需要从这个对象中进一步提取。 * 它主要包含响应状态与元数据响应体流这两类信息。 * response对象 ‌http响应包含状态码、头信息、数据流入口。 * * 属性 * 响应状态与元数据 * ok‌布尔值如果状态码在200-299之间表示成功则为true。状态码在400及以上比如404找不到资源、500服务器报错等则为false。 * status‌数字值表示具体的状态码。 * headers‌一个Headers对象包含服务器返回的所有响应头如Content-Type、Set-Cookie等。 * url‌一个字符串表示最终的url地址如果有重定向它就是重定向后的地址。 * 响应体流 * body‌一个ReadableStream可读流真正的数据json、文本、图片二进制等就在这里面但它是‌流式‌的不能直接读取。 * * 方法 * 介绍 * 该对象提供的方法返回的都是‌Promise对象这是因为该对象中的响应体是以‌数据流Stream的形式接收的而读取和解析这个数据流是一个‌异步操作‌。Promise正是用来处理这种异步操作的JavaScript标准机制。 * 当服务器开始返回响应时数据是分批chunk传输的而不是一次性全部到达。这些方法需要‌等待所有数据块接收完毕‌然后才能进行整体解析而这个“等待解析”的过程天然就是异步的。 * 返回Promise使得主线程可以继续处理其他任务数据准备好后再通过Promise的.then()或async/await来处理。 * * 常用 * json()将响应体流解析为json字符串。 * text()‌将响应体流解析为纯文本。 * blob()将响应体流解析为二进制大对象Blob对象。常用于图片、文件下载、音频视频等场景。 * formData()‌将响应体流解析为表单数据FormData对象。常用于处理 multipart/form-data响应场景。 * arrayBuffer()‌将响应体流解析为原始二进制缓冲区ArrayBuffer对象。 * * 总结 * 这些方法本身不直接返回数据而是返回一个“承诺”Promise这个“承诺”在未来会给你数据。 * * 注意 * 该对象的body流只能被读取‌一次‌一旦调用了response.json()或response.text()那么流就被消耗完了。 * 如果你需要同时用两种方式读取比如既要看文本又要看json必须先调用response.clone()创建一份副本。 * */ if(response.ok) { return response.json(); //调用response对象提供的json()方法把响应体流解析成json格式字符串return的结果传递给下一个then() } throw new Error(响应状态码 response.status); }) .then(function(data) { console.log(服务器响应的数据为, data); return data; }) .catch(function(error) { //抓取错误这里除了可以抓取之前的.then()抛出的Error对象以外还可以抓取到因为断网而导致的失败对象甚至还可以抓取到响应体流解析失败的错误 alert(error.message); //弹窗提示 throw error; //抛出错误由外部调用者决定如何处理 }); } /**** *pre * 介绍 * 发送json数据的http请求。发送请求时http协议报文内携带的内容为一个json字符串。 * * * * 注意 * Content-Type:application/json 。 * * * * 参数 * url请求地址。 * * json_string一个json字符串例如{username:zhangsan, age:16, address:北京} 。 * * * * 知识 * json的官方规范RFC 8259 * ①json内的元素的“键”必须加双引号 单引号或者不加引号都是非法的。 * ②json内的元素的“值”如果为字符串类型的话那么必须用双引号 包裹千万不能使用单引号 否则也是非法的。 * ③json内的元素的“值”不支持undefined只能是字符串、数字、布尔值、null、对象、数组。 * ④json内不能包含方法或函数json只能表示“纯数据”。 * ⑤json内不能包含代码注释标准json不支持注释。 * * json和js对象的区别 * js对象的本质为一段可执行的js代码而json的本质为一种纯文本的数据交换格式。 * * json和js对象互转 * 方法 * JSON.stringify(...) 将一个js对象或数组“转换序列化”为一个“标准”的json字符串。 * JSON.parse(...) 将一个json字符串“解析反序列化”为一个“js对象”。 * * 示例 * 已知js对象 * const user { * username: zhangsan, * age: 16, * address: 北京 * }; * 转换为json字符串 * {username:zhangsan, age:16, address:北京} 。 * * 注意 * 在使用“JSON.stringify(...)”时有以下几样东西是无法被转换的 * ①函数如果一个js对象内含有函数的话转换时会被直接忽略丢弃。 * ②undefined值会被直接忽略丢弃。 * ③Symbol会被直接忽略丢弃。Symbol是ES62015年引入的一种全新的基本数据类型。 * 示例 * 已知js对象 * const obj { * name: zhangsan, * age: undefined, * sayHi: function() { console.log(Hi); } * }; * 转换为json字符串 * {name:zhangsan} */pre *****/ function jsonHttpRequest(url, json_string) { console.log(准备发送请求); return fetch(url, { method: POST, headers: { Content-Type: application/json }, //必需要有这个请求头 body: json_string }) .then(function(response) { if(response.ok) { return response.json(); } throw new Error(响应状态码 response.status); }) .then(function(data) { console.log(服务器响应的数据为, data); return data; }) .catch(function(error) { alert(error.message); throw error; }); } /**** *pre * 介绍 * 发送form表单数据的http请求。发送请求时http协议报文内携带的内容为form表单要提交的数据包括文件上传。 * * * * 注意 * Content-Type:multipart/form-data; boundary---- 。 * * * * 参数 * url请求地址。 * * form_element一个form元素表单元素。 * * * * 原理 * 将整个form表单要提交的数据封装为一个FormData对象最后在使用fetch发送http请求时通过构造参数对象传递过去从而实现发送“携带参数的http请求”。 * * FormData对象 * ①它是js的原生对象所以不用依赖其它库。 * ②它会自动收集表单内的各种控件的数据例如select、textarea、input、text、radio、checkbox、file、date、number 等。 * ③它会自动忽略disable、无name属性的控件。 * ④支持文件上传 */pre *****/ function multipartFormDataHttpRequest(url, form_element) { console.log(准备发送请求); const formData new FormData(form_element); //自动把表单要提交的数据封装成FormData return fetch(url, { method: POST, body: formData }) .then(function(response) { if(response.ok) { return response.json(); } throw new Error(响应状态码 response.status); }) .then(function(data) { console.log(服务器响应的数据为, data); return data; }) .catch(function(error) { alert(error.message); throw error; }); } /**** *pre * 介绍 * 发送form表单数据的http请求。发送请求时http协议报文内携带的内容为form表单要提交的数据但不包括文件上传。 * * * * 注意 * Content-Type:application/x-www-form-urlencoded;charsetUTF-8 。 * * * * 参数 * url请求地址。 * * form_element一个form元素表单元素。 * * * * 原理 * 将整个form表单要提交的数据封装为一个FormData对象然后再封装为URLSearchParams对象最后在使用fetch发送http请求时通过构造参数对象传递过去从而实现发送“携带参数的http请求”。 * * URLSearchParams对象 * ①它是js的原生对象所以不用依赖其它库。 * ②它会自动收集表单内的各种控件的数据例如select、textarea、input、text、radio、checkbox、date、number 等。 * ③它会自动忽略disable、无name属性的控件。 * ④不支持文件上传。 */pre *****/ function simpleFormDataHttpRequest(url, form_element) { console.log(准备发送请求); const formData new FormData(form_element); //自动把表单要提交的数据封装成FormData const urlSearchParams new URLSearchParams(formData); return fetch(url, { method: POST, body: urlSearchParams }) .then(function(response) { if(response.ok) { return response.json(); } throw new Error(响应状态码 response.status); }) .then(function(data) { console.log(服务器响应的数据为, data); return data; }) .catch(function(error) { alert(error.message); throw error; }); }