原生js实现http请求--模拟jquery的ajax函数
js原生方式发送http请求
1.基本原理
使用原生JavaScript调用API可以通过XMLHttpRequest
对象来发送HTTP请求。下面是一个示例代码:
var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
xhr.open('GET', 'https://api.example.com/data'); // 设置请求的URL和类型(这里为GET)
xhr.onreadystatechange = function() { // 定义状态改变时的处理函数
if (xhr.readyState === 4 && xhr.status === 200) { // 当请求完成且返回正常结果时
var responseData = JSON.parse(xhr.responseText); // 将返回的JSON字符串转换为对象或其他格式
console.log(responseData); // 输出获取到的数据
} else {
console.error("Error occurred while fetching data."); // 若有错误则打印错误信息
}
};
xhr.send(); // 发送请求
上述代码中,我们首先创建了一个XMLHttpRequest
对象,然后使用open()
方法指定要发送的请求的URL和类型(此处为GET请求)。在onreadystatechange
事件处理程序中,我们判断请求的状态和返回的状态码,如果都符合条件,就将返回的数据进行处理并输出;否则,会显示相应的错误消息。最后,我们使用send()
方法发送请求。
附:readyState
的不同值,代表了不同的状态。当其变为4
, 就可以访问从服务器返回的数据了。
readyState
状态枚举:
0:尚未初始化
1:正在加载
2:加载完毕
3:正在处理
4:处理完毕
另附http
请求相应代码:
200: 请求成功
202: 请求被接受但处理未完成
400: 错误请求
404: 请求资源未找到
500: 内部服务器错误
status
返回200
,代表请求成功了。
2.@RequestParam方式传参
如果后端接口接收参数是采用@RequestParam
注解接收参数,即URL-Encoded
方式传参。
Tips:
@RequestParam
用来处理Content-Type
为application/x-www-form-urlencoded
编码的内容,Content-Type
默认为该属性。
示例代码如下:
//URL-Encoded方式传参
const xhr = new XMLHttpRequest;
xhr.onloadend = function () {
// 接收请求后端返回的数据
let result = xhr.responseText;
// console.log(result);
// 由于大部分接口返回的数据都是JSON格式,所以需要转化
const data = JSON.parse(result)
console.log(data); // 可查看转化后的数据
document.getElementById("Certificate").value = data.data.certificate;
}
var url = "https://www.baidu.com/getUserInfo";//地址为伪地址,随便写的
xhr.open("post", url);//如果是get请求,改成get即可
// 设置请求头
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//URL-Encoded params方式参数
// 参数设置在send里面,参数+值
var params = {"userName": "xiaohuihui", "pwd": "88888888"};
xhr.send("params=" + JSON.stringify(params).toString());//这里的key是params,value为一个JSON字符串
注意:
上面示例采用的是XMLHttpRequest
的onloadend
方法监听返回结果,也是可以的。XMLHttpRequest
相关的监听事件有:
onabort:当request被停止时触发.
onerror:当request遭遇错误时触发。
onload:请求成功完成时触发。
onloadend:当请求结束时触发,无论请求成功(load)还是失败(abort 或 error)。
onloadstart:接受到响应数据时触发。
onprogress:当请求接收到更多数据时,周期性触发。
timeout: 在预设时间内没有接收到响应时触发
3.@RequestBody方式传参
先介绍一下@RequestBody
的使用场景:
注解@RequestBody
接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded
编码格式的数据,比如:application/json
、application/xml
等类型的数据。
就application/json
类型的数据而言,使用注解@RequestBody
可以将body里面所有的json数据传到后端,后端再进行解析。
示例代码如下:
const xhr = new XMLHttpRequest;
xhr.onloadend = function () {
// 接收请求后端返回的数据
let result = xhr.responseText;
// console.log(result);
// 由于大部分接口返回的数据都是JSON格式,所以需要转化
const data = JSON.parse(result)
console.log(data); // 可查看转化后的数据
document.getElementById("Certificate").value = data.data.certificate;
}
var url = "https://www.baidu.com/getUserInfo";//地址为伪地址,随便写的
xhr.open("post", url);
// 设置请求头
xhr.setRequestHeader("Content-Type", "application/json");//json格式参数
// 参数设置在send里面,json格式参数
var params = {
"userName": "xiaohuihui",
"pwd": "88888888"
};
xhr.send(JSON.stringify(params));
与URL-Encoded
传参方式不一样的地方,主要是请求头中Content-Type
的值。
2024-07-02 14:16:30【出处】:https://blog.csdn.net/weixin_36152775/article/details/135637529
=======================================================================================
原生js实现http请求--模拟jquery的ajax函数
有时页面用到请求,但又不想引入jquery或者其他网络请求,增加代码冗余,增加对代码简便化,那不使用ajax情况下,可以直接使用原生js进行封装函数。原生的js通过XMLHttpRequest 对象进行的的。具体可查阅W3school的XMLHttpRequest 对象。
1、封装可供请求调用的函数
function httpRequest(paramObj,fun,errFun) { var xmlhttp = null; /*创建XMLHttpRequest对象, *老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP") * */ if(window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }else if(window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } /*判断是否支持请求*/ if(xmlhttp == null) { alert('你的浏览器不支持XMLHttp'); return; } /*请求方式,并且转换为大写*/ var httpType = (paramObj.type || 'GET').toUpperCase(); /*数据类型*/ var dataType = paramObj.dataType || 'json'; /*请求接口*/ var httpUrl = paramObj.httpUrl || ''; /*是否异步请求*/ var async = paramObj.async || true; /*请求参数--post请求参数格式为:foo=bar&lorem=ipsum*/ var paramData = paramObj.data || []; var requestData = ''; for(var name in paramData) { requestData += name + '='+ paramData[name] + '&'; } requestData = requestData == '' ? '' : requestData.substring(0,requestData.length - 1); console.log(requestData) /*请求接收*/ xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { /*成功回调函数*/ fun(xmlhttp.responseText); }else{ /*失败回调函数*/ errFun(); } } /*接口连接,先判断连接类型是post还是get*/ if(httpType == 'GET') { xmlhttp.open("GET",httpUrl,async); xmlhttp.send(null); }else if(httpType == 'POST'){ xmlhttp.open("POST",httpUrl,async); //发送合适的请求头信息 xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(requestData); } }
2、调用方法
/*请求参数*/ var paramObj = { httpUrl : 'https://mp.csdn.net', type : 'get', data : { name : 'xuexi', sex : '学习' } } /*请求调用*/ httpRequest(paramObj,function(respondDada) { //这里编写成功的回调函数 console.log(respondDada) },function() { alert('网络错误') });
3、总结
在简单的Html页面不需要引入额外的类库时,可以使用原生请求,或者是引入的库,不满足自己的需求时,可以使用原生来达到自己的需要,掌握原生是根本,其他都是变种;
2024-07-02 11:34:50【出处】:https://blog.csdn.net/u010774409/article/details/136671702
个人使用
根据上面封装的类库,我自己做了部分调整,主要是为了兼容现有的ajax的请求代码和参数类型
function ajaxRequest(paramObj,successFun,errorFun) { var xmlhttp = null; /*创建XMLHttpRequest对象, *老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP") * */ if(window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }else if(window.ActiveXObject) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } /*判断是否支持请求*/ if(xmlhttp == null) { alert('你的浏览器不支持XMLHttp'); return; } /*请求方式,并且转换为大写*/ var httpType = (paramObj.type || 'GET').toUpperCase(); /*数据类型*/ var dataType = paramObj.dataType || 'json'; /*请求接口*/ var url = paramObj.url || ''; /*是否异步请求*/ var async = paramObj.async || true; /*请求参数--post请求参数格式为:foo=bar&lorem=ipsum*/ var paramData = paramObj.data || []; var requestData = ''; for(var name in paramData) { requestData += name + '='+ paramData[name] + '&'; } requestData = requestData == '' ? '' : requestData.substring(0,requestData.length - 1); /*请求接收,可以监听onreadystatechange,或onloadend事件*/ xmlhttp.onloadend = function() { if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { /*成功回调函数*/ successFun != undefined ? successFun(xmlhttp.responseText) : paramObj.success(xmlhttp.responseText); }else{ /*失败回调函数*/ console.error("Error occurred while fetching data."); // 若有错误则打印错误信息 errorFun != undefined ? errorFun(xmlhttp, xmlhttp.status, "error...") : paramObj.error(xmlhttp, xmlhttp.status, "error..."); } } /*接口连接,先判断连接类型是post还是get*/ if(httpType == 'GET') { xmlhttp.open("GET",url,async); xmlhttp.send(null); }else if(httpType == 'POST'){ xmlhttp.open("POST",url,async); //发送合适的请求头信息 xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send(requestData); } } /*请求参数配置*/ ajaxConfig={ type: 'get', url: 'http://timor.tech/api/holiday/year/?type=Y&week=N', dataType: 'json', data : { name : 'xuexi', sex : '学习' }, success: function(data) { console.log('success', data) }, error: function(xhr, textstatus, error) { console.log('error', textstatus, error) } } /*请求调用*/ ajaxRequest(ajaxConfig)
具体的使用示例,可参考万年历:万年历(hao123)代码
=======================================================================================
对原生HTTP请求的理解与总结
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10946165.html,多谢,=。=~
术语
HTTP:超文本传输协议,规定Web浏览器如何从Web服务器获取文档和向Web服务器提交表单内容,以及Web服务器如何响应这些请求和提交;
(HTTP不在脚本控制下,只当用户点击链接、提交表单、输入URL时发生。但是js可操纵HTTP,例如设置window对象的location属性、调用表单的submit()方法会初始化HTTP请求,页面会重新加载。)
Ajax:使用脚本操纵HTTP的Web应用架构,实现与Web服务器的数据交换,不会导致页面重载,客户端从服务器“拉”数据,可利用XMLHttpRequest对象实现;
Comet:使用脚本操纵HTTP的Web应用架构,与Ajax相反,服务器向客户端“推”数据,可利用EventSource对象实现;
XMLHttpRequest:定义了用脚本操纵HTTP的API;
(XMLHttpRequest对象支持包括XML在内的任何基于文本的格式,能用于HTTP和HTTPS请求,涉及HTTP请求或响应的所有活动)
XMLHttpRequest的使用
实例化(IE7及以后):
var request = new XMLHttpRequest();
模拟XMLHttpRequest构造函数(IE5、IE6):
if (window.XMLHttpRequest === undefined) { window.XMLHttpRequest = function() { try { return new ActiveXObject("MSXML2.XMLHttp.6.0"); } catch (e1) { try { return new ActiveXObject("MSXML2.XMLHttp.3.0"); } catch (e2) { throw new Error("XMLHttpRequest is not supported"); } } } }
HTTP请求(请求的方法或动作、请求的URL、请求头、请求体):
request.open("GET", "/log.php"); // 请求的方法、URL request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); // 请求头 request.send(null); // 请求体
HTTP响应(数字+文字的状态码、响应头、响应体):
request.onreadystatechange = function() { // HTTP的请求状态readyState // 0:open尚未调用 // 1:open已调用 // 2:接收到头信息 // 3:接收到响应主体 // 4:响应完成 // HTTP状态码status // 2xx:代表请求已成功被服务器接收、理解、并接受 if(request.readyState === 4 && request.status === 200) { // responseText属性:MIME类型的文本响应,如:text/css // responseXML属性:Document对象类型,如:XML、XHTML console.log(request.responseText); } };
响应解码
request.onreadystatechange = function() { if (request.readyState === 4 && request.status === 200) { var type = request.getResponseHeader("Content-type"); if (type.indexOf("xml") !== -1 && request.responseXML) { console.log(request.responseXML); // Document对象响应 } else if (type === "application/json"){ console.log(JSON.parse(request.responseText)); // Json响应 } else { console.log(request.responseText); // 字符串响应 } } };
请求主体编码(POST请求)
1、表单编码(对名字和值进行URL编码(即使用十六进制转义码替换特殊字符)、使用=分开编码后的名字和值、使用&连接名/值对)
PS:<input type="submit">定义用于向表单处理程序(form-handler)提交表单的按钮,自带表单编码功能。
POST请求必须设置请求头:
request.open("POST",url);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); request.send(encodeFormData(data));
GET请求只需跟在url连接后即可:
request.open("GET", url + "?" + encodeFormData(data)); request.send(null);
表单编码函数encodeFormData:
// 对象属性的表单编码 function encodeFormData(data) { if (!data) return ""; // 如果data非对象则返回空字符串 var paris = []; // 保存名=值对 for(var name in data) { if (!data.hasOwnProperty(name)) continue; // 跳过继承属性 if (typeof data[name] === "function") continue; // 跳过方法 var value = data[name].toString(); // 将值转换为字符串 name = encodeURIComponent(name.replace("20%", "+")); // 编码名字 value = encodeURIComponent(value.replace("20%", "+")); // 编码值 paris.push(name + "=" +value); } return paris.join("&"); // 使用"&"连接名/值对 }
2、JSON编码(使用JSON.stringify()方法)
request.open("POST",url); request.setRequestHeader("Content-type","application/json"); request.send(JSON.stringify(data));
3、XML编码(send方法中传递XML Document对象)
<query> <find zipcode="02134" radius="1km"> pizza </find> </query>
function createXML(what, where, radius) { // Create an XML document with root element <query> var doc = document.implementation.createDocument("", "query", null); var query = doc.documentElement; // <query>元素 var find = doc.createElement("find"); // 创建<find>元素 query.appendChild(find); // 把<find>添加至<query>中 find.setAttribute("zipcode", where); // 设置<find>的属性 find.setAttribute("radius", radius); find.appendChild(doc.createTextNode(what)); // 设置<find>的内容 return doc; } // 会自动设置Content-type头 request.send(createXML("pizza", "02134", "1km"));
4、文件上传
HTML表单<input type="file">始终能上传文件;XMLHTTPRequest无法实现;XHR2可以通过向send()方法传入File对象实现(文件类型是更通用的二进制大对象Blob类型中的一个子类型)。
5、multipart/form-data请求
当HTML表单同时包含文件上传元素和其他元素时,必须使用Content-type为multipart/form-data的特殊方式提交表单,该编码使用长“边界”字符串把请求主体分离成多个部分。
XHR2定义了新的FormData API,容易实现多部分请求主体(使用FormData()构造函数创建FormData对象,然后按需多次调用这个对象的append()方法把个体的“部分”(字符串、File或Blob对象)添加到请求中)。
function createFormData(data) { if (typeof FormData === "undefined") { throw new Error("FormData is not implemented"); } var formData = new FormData(); for(var name in data) { if (!data.hasOwnProperty(name)) continue; var value = data[name]; if (typeof value === "function") continue; formData.append(name, value); } return formData; } request.send(createFormData({user: "aaa", text: "bbb"}));
HTTP请求无法完成的3种情况
1、timeout事件:请求超时;
2、abort事件:请求中止;
3、error事件:比如太多重定向这样的网络错误会阻止请求完成;
2024-07-02 11:38:09【出处】:https://www.cnblogs.com/dreamsqin/p/10946165.html
=======================================================================================
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/18279612
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!