ajax必须运行在有服务器开启的网页当中
AJAX - 创建 XMLHttpRequest 对象
XMLHttpRequest 是 AJAX 的基础。
ajax的实现步骤:
ajax在没有经过特殊的设置时,只能访问同源的网站
//1.创建ajax对象
var xhr = new XMLHttpRequest();
//2.告诉ajax请求地址以及请求方式
xhr.open('get','http://www.example.com');
//3.发送请求
xhr.send();
//4.获取服务器端给与客户端的响应数据
xhr.onload = function(){
console.log(xhr.responseText);
//xhr.responseText返回值是String
}
ajax属于JavaScript代码,要写在script标签内
XMLHttpRequest 对象会代替浏览器给服务器发送信息
xhr.sned()方法不能直接接受服务器返回的结果,必须使用noload事件
使用ajax发送请求参数时,请求参数需要手动拼接
get请求是不能提交json对象数据格式的,传统网站的表单提交也是不支持json对象数据格式的,超大型文本数据适合post请求提交到服务器
ajax状态码:表示ajax请求的过程状态,是由ajax对象返回的
http状态码:表示请求的处理结果,是由服务器端返回的
ajax封装:
function ajax(options){
//储存默认值
var defaults = {
type:'get',
url:'',
data:{},
header:{'Content-Type':'application/x-www-form-urlencoded'},
success:function(){},
error:function(){}
}
//使用options中的对象属性覆盖defaults中的对象属性
//有新的值就会覆盖,没有就用原来的值
Object.assign(defaults,options);
//创建ajax对象
var xhr = new XMLHttpRequest();
//拼接请求参数的变量
var params = '';
//循环用户传递进来的对象格式参数
for(var attr in defaults.data){
//将参数转换为字符串格式
params += attr + '=' + defaults.data[attr] + '&';
}
//将参数最后面的&截取掉
//将截取的结果重新赋值给params变量
params = params.substr(0,params.length-1);
//判断请求方式
if(defaults.type == 'get'){
defaults.url = defaults.url + '?' +params;
}
//配置ajax对象
xhr.open(defaults.type,defaults.url);
//如果请求方式为post
if(defaults.type == 'post'){
//用户希望的向服务器端传递的请求参数的类型
var contentType = defaults.header['Content-Type'];
//设置请求参数格式的类型
xhr.setRequestHeader('Content-Type',contentType);
//判断ajax函数传入对象中希望的请求参数的类型
//如果是json类型
if(contentType == 'application/json'){
//向服务器端传递json数据格式的参数
xhr.send(JSON.stringify(defaults.data));
}
else{
//向服务器端传递普通类型的请求参数
xhr.send(params);
}
}else{
//发送请求
xhr.send();
}
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function(){
//获取响应头中的数据
var contentType = xhr.getResponseHeader('Content-Type');
//服务器端返回的数据
var responseText = xhr.responseText;
if(contentType.includes('application/json')){
//将json字符串转换为json对象
responseText = JSON.parse(responseText);
}
//当http状态码为200的时候
if(xhr.status == 200){
//请求成功,调用处理成功情况的函数
defaults.success(responseText,xhr);
}
else{
//请求失败,调用处理失败情况的函数
defaults.error(responseText,xhr);
}
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
data:{
name:'zhangsan',
age:20
},
header:{
'Content-Type':'application/json'
},
success:function(data){
console.log('这里是success函数'+data);
},
error:function(data,xhr){
console.log('这里是error函数')
}
})
客户端的art-template模板引擎
template第一个参数是模板id,第二个参数是一个对象,对象中储存要拼接的数据
FormData对象的作用:
1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
2.异步上传二进制文件
1.准备HTML表单
<form id="form">
<input type="text" name='username'>
<input type="password" name='password'>
<input type="button">
</form>
2.将HTML表单转化为formData对象
var form = document.getElementById('form');
var formData = new FormData(form);
3.对表单进行配置,提交表单对象
xhr=new XMLHttpRequest();
xhr.open('post','http://localhost:3000/formData');
xhr.send(formData);
4.监听xhr对象下的onload对象
xhr.onload = function(){
//对象http状态码进行判断
if(xhr.status == 200){
console.log(xhr.renponseText);
}
}
FormData对象的实例方法:
1.获取表单对象中属性的值
formData.get(‘key’);
2.设置表单对象中属性的值
formData.set(‘key’,‘value’);
ajax请求限制:
ajax只能向自己的服务器发送请求,两个不同源的网站之间不能互相发送信息
1同源(是不是同一个服务器):如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
在script标签中的src属性中输入请求地址,就会执行服务器端的代码,由于服务器端返回的代码是个函数并且被客户端接收,所以客户端就会执行相同函数名称的函数·
点击按钮动态发送请求,并且在请求完成之后删除script标签
优化代码:
把函数的名称变为形式参数传递到服务器端,服务器端接收参数之后再返回一样的参数
代码的封装:
function jsonp(options){
//动态创建script标签
var script = document.createElement('script');
//拼接字符串的变量
var params = '';
for(var attr in options.data){
params += '&' +attr + '=' +options.data[attr];
}
//随机生成函数的名字
var fnName = 'myJsonp'+Math.random().toString().replace('.','');
//把options.success变成为一个全局函数,.后面不能跟变量
window[fnName] = options.success;
//为script标签添加scr属性
script.src = options.url+'?callback='+fnName;
//将script标签追加到页面中
document.body.appendChild(script);
//为script标签添加onload事件
script.onload = function(){
document.body.removeChild(script);
}
}
jsonp({
//请求地址
url:'http://localhost:3001/better',
data{
name:'lisi',
age:30
},
success:function(data){
console.log(data);
}
})
//把jsonp放在点击事件当中即可
jsonp是express框架下给的方法,接收客户端传递过来的请求参数,将数据转化为字符串,再与请求地址拼接好,返回客户端
CORS:跨域共享资源,它允许浏览器向浏览器向跨域服务器发送ajax请求,克服了ajax只能同源使用的限制
客户端:
<button id='btn'>点我发送请求</button>
//获取按钮
var btn = document.getElementById('btn');
btn.onclick = function(){
ajax({
type:'get',
url:'http://localhost:3001/cross',
success:function(data){
console.log(data);
}
})
}
服务器端:
app.use((req,res)=>{
//1.允许哪些客户端访问我
//*代表允许所有的客户端访问我
res.header('Access-Control-Allow-Origin','*');
//2.允许客户端使用哪些请求访问我
res.header('Access-Control-Allow-Methods','get,post');
//3.允许客户端发送请求时携带cookie信息
res.header('Access-Control-Allow-Credentials',true);
next();
})
第三方模块request:向其他的服务器端请求数据
var request = require('request');
request(url,function(error,response,body){
//url:请求地址 error:错误对象 response:服务器端的响应信息 body:响应的主体内容
})
在使用ajax技术发送请求跨域请求时,默认情况下不会在请求中携带cookie信息
解决办法:withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false
Access-Control-Allow-Credentials:true 允许客户端发送请求时携带cookie信息
当发送跨域请求时,携带cookie信息
xhr.withCredentials = true;
jQuery中ajax方法:
$.ajax()方法:
$.ajax({
type:'get',
url:'http://www.example.com',
//data中也可以直接传递字符串参数,用&符号进行分割多个参数值
data:{ name:'zhangsan',age:'20' },
//指定参数传递的类型来匹配服务器的要求 application/json可以设置为json字符串类型的参数值
//application/x-www-form-urlencoded为默认值,就是&分割参数的类型
//在contentType中设置什么样的参数类型,data中就要传递什么样的参数类型
//JSON.stringify可以把json对象转化为json字符串
contentType:'application/x-www-form-urlencoded',
//在请求发送之前执行的函数
beforeSend:function(){
//return false可以阻止发送请求
return false
},
//请求成功之后执行的函数,response为服务器端返回的信息,方法内部会自动将json字符串转换为json对象
success:function (response){},
//请求错误的函数
error:function(xhr){}
});
serialize方法:将表单中的数据自带拼接为字符串类型的参数,参数名=参数值,用&符号分割参数的类型
<form id="form">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="提交">
</form>
<script src='/js/jquery.mim.js'></script>
<script type="text/javascript">
$('#form').on('submit',function(){
//将表单内容拼接成字符串类型的参数
var params = $('#form').serialize();
serializeObject($(this));
return false;
})
//将表单中用户输入的内容转换为对象类型
function serializeObject(obj){
//定义一个空变量来储存数组的值
var result={};
//将表单中的内容以数组的方式储存,每个元素都是一个表单对象
//[{name:"username",value:"zhangsan"},{name:"password",value:"123456"}]
var params = obj.serializeArray();
//对数组进行循环遍历,将数组转换为对象类型,index为下标,value为每一个对象
$.each(params,function(index,value){
result[value.name]=value.value;
})
return result;
}
</script>
发送jsonp请求:
客户端:
$.ajax({
url:'http://localhost:3000/jsonp,
//指定当前发送jsonp请求
dataType:'jsonp',
//修改callback参数名称
jsonp:'cb',
//指定函数名称,如果设置该属性,必须自己在全局作用域下准备该函数,不执行success函数
//jsonCallback:'fn',
success:function(response){
console.log(response);
}
})
服务器端:
app.get('/jsonp',(req,res)=>{
const cb = req.query.cb;
const data = cb+"({name:'zhaoliu'})";
res.send(data);
})
$.get方法用于发送get请求,$.post方法用于发送post请求
$.get(url,{},function(response){})
$.post(url,{},function(response){})
jQuery中ajax全局事件
只要页面中有ajax请求被发送,对应的全局事件就会被触发
.ajaxStart() //当请求开始发送时触发
.ajaxComplete() //当请求完成时触发
//当页面中有ajax请求发送时触发
$(document).on('ajaxStart',function(){
console.log('start');
})
//当页面中有ajax请求完成时触发
$(document).on('ajaxComplete',function(){
console.log('complete');
})