前后端交互深究
前后端交互深究
1. 默认的表单提交请求
1.1 表单的GET请求
表单请求为GET请求方式时,表单的数据会以键值对的方式(name对应value)添加到URL后面,所以不安全,一般用于获取数据,传入特定参数,后端根据接收到的参数到数据库中查找数据再返回给客户端
Node服务端(Express框架)可以通过req.query来获取GET请求发送给服务端的数据(对象形式)
1.2 表单的POST请求
表单请求为POST请求时,表单数据不会添加到URL后面,而且理论上传输的数据量是无限的,所以一般用于传输数据给服务端
Node服务端(Express框架)借用第三方中间件body-parser可以通过req.body获取数据(对象形式)
1.3 表单的enctype属性
该属性规定在发送到服务器之前应该如何对表单数据进行编码
默认值为“application/x-www-form-urlencoded”,指在发送到服务器之前,所有字符都会进行编码:空格转换为”+“加号,特殊字符转换为ASCII HEX值
当使用multiparty/form-data时,传输的一般都是文件,图片,音乐等等非文本值,传输的方式是以二进制数据传输给服务端的,在服务端(Express框架)只能用以下方式读取到数据:
app.post('/',function(req,res){
req.on('data',function(data){
console.log(data);//二进制数据
console.log(data.toString());//转换为字符串格式
});
});
当使用text/plain时,传输的方式也是二进制数据传输,在服务端也只能以上面的这个方式读取到数据
强烈建议:一般情况下,使用默认值application/x-www-form-urlencoded即可,也是最佳方案,因为便于服务端接收数据,1.1与1.2的例子都是默认值情况下传输数据的,对服务端很友好。对于表单中存在file控件时,就得使用属性值multipart/form-data(必须),服务端接收数据就得使用上述方法。对于需要发送邮件时就得使用第三种属性值,否则会出现接收时编码错误情况(在网上看的,具体的没有实践)
2. AJax请求(同源政策限制)
2.1 GET请求
在Ajax中,GET请求与表单中GET请求大同小异,不同的是就是得将传输的数据手动添加到URL后且要符合格式
在Node服务端同样的得用req.juery来取得数据
2.2 POST请求
POST请求与表单中POST请求大部分相同,不同的是客户端得对传输给服务端的数据自己进行设置
在Ajax中,POST请求发送数据通过send方法
经了不起的在下实践,目前有两种方法比较友好:
2.2.1 application/x-www-form-urlencoded格式
var xhr=new XMLHttpRequest();
xhr.open("POST",url);
//设置请求头内容格式,必须设置且只能在open方法之后设置,如果不设置,对服务端很不友好,取不到数据
//而且客户端也很难识别数据格式,默认都是text/plain格式,服务端取不到数据
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send('key1=value1&key2=value2');//键值对格式
xhr.onload=function(){};
2.2.2 application/json格式
var obj={
name:'caiyun',
age:18
};
var xhr=new XMLHttpRequest();
xhr.open("POST",url);
//设置请求头内容格式,必须设置且只能在open方法之后设置,如果不设置,对服务端很不友好,取不到数据
//而且客户端也很难识别数据格式,默认都是text/plain格式,服务端取不到数据
xhr.setRequestHeader('Content-type','application/json');
xhr.send(JSON.stringify(obj));//json格式
xhr.onload=function(){};
2.3 服务端如何取得数据
经了不起的在下实践证明:都可以利用Express框架中间件body-parser来获取数据
3. Jquery中的Ajax
3.1 GET请求
3.2 POST请求
经了不起的在下实践:Jquery中的Ajax由于进行了封装,只要在data属性中写入的东西都会被传输到服务端,只不过格式要注意:
字符串形式:
data属性中可以传入字符串,且要符合application/x-www-form-urlencoded格式,即键值对格式
$.ajax({
url:url,
type:'get',
data:'key1=value1&key2=value2',
success:function(res){
console.log(res);
}
});
对象形式:
data属性中也可以传入对象(猜测会自动转换),对客户端就很友好了,方便了许多
$.ajax({
url:url,
type:'get',
data:{
key1:value1,
key2:value2
},
success:function(res){
console.log(res);
}
});
GET请求与POST请求都支持这两种传输格式,可以,这很友好
并且:
到目前为止,发现了这么一个规律:
只要是GET请求传输数据,在Node服务端(Express框架)都是通过req.query获取数据
只要是POST请求传输数据,在Node服务端(Express)都可以通过中间件body-parser来获取数据
总结:这很友好
4. Jsonp跨域请求
该方法虽然绕过了同源政策的限制,但是需要服务端配合
该方法主要利用script标签的特性
客户端代码:
var script=document.createElement('script');
script.src=url+'?'+'callback=funcName';//目标ip地址+传入回调函数名
document.body.appenChild(script);
function Test(data){
console.log(data);
};
服务端代码:
res.send(`Test(${data})`);
服务端返回的字符串会作为客户端script标签引入的内容,浏览器就会对该内容解析执行,这样就可以用预先定义好的回调函数对连带着一起返回的数据(字符串形式或者json格式)进行处理,这就是Jsonp的基本原理
在一个页面中,所有引入的JavaScript文件和script标签内的代码都共享同一片天空
下面发放福利,根据了不起的在下看的视频封装了一个Jsonp方法:
function jsonp(url, params, callback) {
var funcName = 'jsonp_' + Date.now() + Math.random().toString().substr(2, 5);//生成一个随机的回调函数名字
if (typeof params === 'object') {
// 如果传入的数据是对象,那就将其转换成键值对格式的字符串
var tempArr = [];
for (var key in params) {
var value = params[key];
tempArr.push(key + '=' + value);
}
params = tempArr.join('&');
}
var script = document.createElement('script');
script.src = url + '?' + params + '&callback=' + funcName;
document.body.appendChild(script);
window[funcName] = function (data) {
callback(data);
delete window[funcName];
document.body.removeChild(script);
};
}
很友好很强大!
5. Jquery中的Jsonp跨域请求
JQuery中的Jsonp方法只是对原生JavaScript中的Jsonp方法进行了封装,所以使用起来相当方便
注意:与原生Javascript中一样,只支持GET请求,因为script标签就是GET请求
$.ajax({
url:url,
type:'get',
dataType:'jsonp',
success:function(res){
console.log(res);
}
});
与原生JavaScript中的Jsonp比起来,方便的不是一两点:
同样带了一个随机生成的回调函数名给服务端,当然也可以自己指定回调函数的名字,但是不建议这样写,因为服务端返回的数据在success中一样可以取到,在success中处理返回数据即可
6. CORS跨源资源共享(cross origin resource share)
该跨域方法就只是单纯服务端的任务了,只要服务端设置了响应头为:
res.setHeader('Access-Control-Allow-Origin', '*');
*表示允许任何源向本服务器发送请求