原生Ajax向.NetCore3.X WebApi 传参
本文基于浏览器原生的Ajax请求+Asp.NetCore3.X WebApi进行讲解。其他环境其实本质上也是类似的。
一、Ajax 准备工作。
1. 创建Ajax请求对象
function CreateAjaxXHR() {
//创建核心对象
xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
//for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
2.Ajax基本请求模式
//抽取数据代码
document.getElementById('getQuestion').addEventListener('click', function () {
let xmlhttp = CreateAjaxXHR();
if (xmlhttp === null) {alert('不支持Ajax!'); return; }
xmlhttp.onerror = function (err) {alert(xmlhttp.responseText); };
//编写回调函数
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4) {
//请求成功的处理
if (xmlhttp.status === 200) {
//ToDo:在此进一步处理相关业务逻辑
}
else {alert(xmlhttp.responseText);}
} else
{
//请求失败的相关处理
alert(xmlhttp.responseText);
}
};
//设置Ajax请求方式、数据格式,准备数据内容、发送数据
xmlhttp.open('post', 'Api/controller', true); //true:表异步
xmlhttp.setRequestHeader('content-type', 'application/json'); //指明数据格式
let willSentData={x:1,y:2}; //准备数据,应与上一行代码相匹配
xmlhttp.send(willSentData); //发送数据
});
本文主要讲解在Ajax请求过程中的转参方式(前端发送数据与后端接收数据),因此前台的Ajax请求重点主要集中在以下几行代码上。
//设置Ajax请求方式、数据格式,准备数据内容、发送数据
xmlhttp.open('post', 'Api/controller', true);
xmlhttp.setRequestHeader('content-type', 'application/json');
let willSentData={x:1,y:2};
xmlhttp.send(willSentData);
二、Get 请求
该请求方式特点如下:
参数通过url传递(所以不够安全,容易泄密)
传递的参数是有长度限制(一般是4K)
请求的Url会被浏览器缓存
发送请求时,浏览器会把http header和data一并发送出去,服务器响应200(返回数据),因此Get请求只会产生一个tcp数据包。(这一点比Post方式高效)
根据需要(比如有中文或特殊字符)需对请求地址进行url编码(也只有此一种编码方式)。
无参模式
前台:
xmlhttp.open('get', 'Api/controller', true);
xmlhttp.send();
后台:
[HttpGet]
public string Get()
{ return "ok" }
小提示:如果后台有多个Get方法,可通过 [httpGet属性] 来指定前台访问的路由地址,如下所示(此方式也适应 [httpPost属性] 等):
后台:
[HttpGet]
public string Get1()
{ return "ok" }
[HttpGet("Get2")]
public string Get2()
{ return "ok" }
前台:
xmlhttp.open('get', 'Api/controller', true); //将访问 Get1方法
xmlhttp.open('get', 'Api/controller/Get2', true); //将访问 Get2方法
有参模式(又有两种方式)
(1)拼接参数模式。
注意:后台方式参数的名称与前台传递的参数名称可以不同,但个数、类型必须相同。否则将报“ 415 (Unsupported Media Type) ”错误
前台:
xmlhttp.open('get', 'Api/controller?key1=value1&&key2=2', true);
xmlhttp.send();
后台:
[HttpGet]
public string Get(string key1,int key2 )
{
return "ok"
}
(2)路由参数模式
前台:
xmlhttp.open('get', 'Api/controller/value1/2', true);
xmlhttp.send();
后台:
[HttpGet ("{key1}/{key2}")]
public string Get(string key1,int key2 )
{
return "ok"
}
三、Post 请求
该请求方式特点如下:
参数放在request body中(对.Net core WebApi来说,要视具体情况)
传递的参数无长度限制(但一般大于 2G 时,要进行相关设置)
请求的Url不会被浏览器缓存
发送请求时,浏览器会先发送 http header,收到响应 100 continue 时,再发送data请求数据,服务器响应200(返回数据),因此Post请求会产生二个tcp数据包。
根据需要可对数据进行多种编码,包括url编码。
无参模式
前台:
xmlhttp.open('Post', 'Api/controller', true);
xmlhttp.send();
后台:
[HttpPost]
public string Post()
{
return "ok"
}
有参模式(根据前台参数类型不同,后台接收方式不同)
(1)Json格式数据。
注意:
后台数据模型类中的属性数据类型,必须与前台待发送数据中的相应相属性的数据类型完全一致,否则会报 400 (Bad Request) 错误。
前台在发送数据前必须序列化为 JSON 字符串,否则会报 400 (Bad Request) 错误。
前台:
xmlhttp.open('post', 'Api/controller', true);
xmlhttp.setRequestHeader('Content-Type', 'application/json;charset=utf-8');
let WillSentData={key1:"vaule1",key2:2};
WillSentData = JSON.stringify(WillSentData); //序列化为字符串
xmlhttp.send(WillSentData);
后台:
[HttpPost]
public string Post([FromBody] DataModel P_Data )
{
//说明:DataModel 是一个类,其中有 string key1 和 int key2 两个属性。
return "ok"
}
(2)FormData格式数据
注意:
通过该方式,可以上传文件及其他相关数据;
后台接收时,需通过键名称进行查询具体参数值,其类型均为 Microsoft.Extensions.Primitives.StringValues 即相当于字符串类型。
前台:
xmlhttp.open('post', 'Api/controller', true);
//xmlhttp.setRequestHeader('Content-Type', 'multipart/form-data;charset=utf-8');
//理论上来说,应当加上上一句,但实测过程中,如使用上句代码会报 400 (Bad Request) 错误,不知是不是Bug。不使用反而可以正常运行,且通过调试查询 Content-Type 的值就是multipart/form-data。
let WillSentData=new FormData();
WillSentData.append('UpFileName', InputFileElement.files[0]);
WillSentData.add{(key1,"vaule1");
WillSentData.add{(key2",2);
xmlhttp.send(WillSentData);
后台:
[HttpPost]
public string Post[FromForm] IFormCollection P_Data )
{
//说明:IFormCollection 是表单(From)内各元素的集合。
string key1value=P_Data["key1"];
string key2Value=P_Data["key2"]; //接收到的内容全部为字符串类型数据
FormFile FirstFile = P_Data.Files[0] as FormFile; //接收到的文件
return "ok"
}
四、Patch 请求
特点:
参数放在request body中
具体方式,请参考 Post请求
五、Put 请求
特点:
参数放在request body中
具体方式,请参考 Post请求
六、Delete 请求
特点:
参数通过url传递
具体方式,请参考 Get请求
本文在GitHub地址: