Ajax是一种可以与服务器交换数据并更新部分页面内容,同时可以在不让整个网页重新加载的情况下更新网页的一种技术
var xmlHttp = new XMLHttpRequest();
/*
参数顺序,描述
(1)method:请求的类型;GET 或 POST
(2)url:文件在服务器上的位置
(3)async:true(异步)或 false(同步) (一般为true,因ajax的精髓就是异步)
*/
xmlHttp.open("GET||POST","url 如(./ajax.php)",true)
//注意点:url中不能出现中文,只能数字、字母、ASCII码、下划线
// GET方式的 url格式:./ajax.php?t=123&321......
//如果出现中文也可以用encodeURIComponent方法转换
// POST方式的url不能在后面接字符串传递参数
xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//setRequestHeader 必须放在设置请求与发送请求之间
//下一步在发送请求send中传递参数即可
xmlHttp.send("name=xuyuxin&age=18")
xmlHttp.send();
//监听事件: onreadystatechange 每当请求状态发生变化,就会触发此函数
xmlHttp.onreadystatechange = function (ev2){
/*
readyState 状态变化有以下5种
0:请求未初始化
1:服务器连接已建立
2:请求已接收
3:请求处理中
4:请求已完成,且响应已就绪
*/
if(xmlHttp.readyState === 4){
//请求已完成,并不代表请求成功,因此还需判断是否请求成功
//status是专门判断请求是否成功的状态码
// 状态码大于或等于200并且不能超过300以上,300以上除了304以外全都是请求失败
if(xmlHttp.status >= 200 && xmlHttp.status < 300 || xmlHttp.status === 304){
console.log('请求成功')
}else{
console.log('请求失败')
}
}
}
由于在IE6-IE5以下不支持XMLHttpRequest这个属性,因此会产生错误,在低级浏览器中可以使用ActiveXObject来实现同样的效果
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
在IE低版本中ajax还有缓存的问题,解决这个问题,要url地址不断改变,不能为常量,即可解决
xmlhttp.open("GET","ajax.php?"+(new Date().getTime()),true)
由于在Ajax中浏览器支持的属性不同,单一方案不能支持全部浏览器,有两种解决方案,因此可以把这两种方案合成一种,以便使用
if(window.XMLHttpRuquest){
var xmlHttp = new XMLHttpRequest();
}else{
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
=====================================================================================
var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXOject("Microsoft.XMLHTTP");
/**
* @param {请求的类型}option.type
* @param {发送请求的地址} option.url
* @param {发送请求的数据}option.data
* @param {超时时间} option.timeout
* @param {请求成功后执行的函数*} option.sucess
* @param {请求失败后执行的函数*} option.error
*/
function createAjax(option) {
//0.把传入对象处理成字符串,服务器才可接收
var toStringObj = objToString(option.data);
//1.创建ajax对象,并判断游览器支持那个属性
var xmlHttp = window.XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject("Microsoft.XMLHTTP");
var timer;
if (option.type.toloworCase === "get") {
//2.设置请求方式和地址
xmlHttp.open("GET", option.url + "?" + toStringObj, true);
//3.发送请求
xmlHttp.send();
//4.监听请求状态
} else {
// POST请求方式
xmlHttp.open(option.type, option.url, true);
xmlHttp.setRequestHeader(
"Content-type",
"application/x-www-form-urlencoded"
);
xmlHttp.send(toStringObj);
}
xmlHttp.onreadystatechange = function() {
//请求完成,并不代表请求成功
if (xmlHttp.readyState === 4) {
//判断请求是否成功
if (
(xmlHttp.status >= 200 && xmlHttp.status < 300) ||
xmlHttp.status === 304
) {
clearInterval(timer);
option.sucess(xmlHttp);
} else {
option.error(xmlHttp);
}
}
};
//判断外界是否传入超时时间
if (option.timeout) {
timer = setInterval(function() {
//超时时间到后执行停止此次发送请求,默认为失败
xmlHttp.abort();
clearInterval(timer);
}, option.timeout);
}
}
//把obj转为字符串
function objToString(data) {
var res = [];
data.time = new Date().getTime();
for (var key in data) {
//encodeURLComponent函数对,对象名和属性进行转换,以防出现url中不能出现的字符而出错
res.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return res.join("&");
}
//调用方式
createAjax({
data:{
name: that.getAttribute('name')
},
type:"POST",
timeout:3000,
url:"./ajaxLesson2.php",
sucess:function(xml){
console.log('请求成功');
},
error:function(xml){
console.log("请求失败");
},
});
//调用方式
// ajax对象.要获取的方式
xmlHttp.responseText
1.开头前缀指定版本和编码(必要)
<?xml version="1.0" encoding="UTF-8"?>
2.根目录(必要 和html标签一样要闭合)
<root>
</root>
3.之后标签名不受限制,完整版
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nz>
<title>甜美女装</title>
<des>人见人爱,花间花开,甜美系列</des>
<image>images/1.jpg</image>
</nz>
<bb>
<title>奢华驴包</title>
<des>送女友,送情人,送学妹,一送一个准系列</des>
<image>images/2.jpg</image>
</bb>
<tx>
<title>键盘拖鞋</title>
<des>程序员专属拖鞋, 屌丝气息浓郁, 你值得拥有</des>
<image>images/3.jpg</image>
</tx>
</root>
<?php
//向客户端发送原始的 HTTP 报头。
header("content-type:text/xml;charset=utf-8");
//file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用 内存映射技术来增强性能。
echo file_get_contents("xml文件地址如(./ajax.xml)")
?>
//获取XML传输而来的数据要使用 responseXML方式获取
var Data = xml.responseXML; //返回的是一个document文档对象
//接着使用javascript获取遍历DOM元素
var titleinfo = Data.querySelector(name+'>title'),
des = Data.querySelector(name+'>des'),
image = Data.querySelector(name+'>image');
//最后就可以对DOM里面存储的数据进行操作了
console.log(des.innerHTML);
{
"nz":{
"title":"甜美女装",
"des":"人见人爱,花间花开,甜美系列",
"image":"./images/1.jpg"
},
"bb":{
"title":"奢华驴包",
"des":"送女友,送情人,送学妹,一送一个准系列",
"image":"./images/2.jpg"
},
"tx":{
"title":"键盘拖鞋",
"des":"程序员专属拖鞋, 屌丝气息浓郁, 你值得拥有",
"image":"./images/3.jpg"
}
}
//在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:
//JSON 键/值对
//JSON 键值对是用来保存 JS 对象的一种方式,和 JS 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值:
"{"firstName": "Json"}"
这很容易理解,等价于这条 JavaScript 语句:
{firstName : "Json"}
//JSON 与 JS 对象的关系
//很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:
//JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
//如:
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
//要实现从JSON对象转换为JS字符串,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
//要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
//当从服务器返回的数据不是标准json字符串时是无法使用parse的,那么可以试试用eval()强制转化和为js对象
//当从服务器返回的数据不是标准json字符串时是无法使用parse的,那么可以试试用eval()强制转化和为js对象
//注意点: 转js对象必须加 "("+data+")"
var Data = eval("("+data+")")
在低版本的IE中, 不可以使用原生的JSON.parse方法, 但是可以使用json2.js这个框架来兼容 json2.js下载地址:
echo file_get_contents(" JSON文件地址 如(./json.txt)");
ajax的请求过程:ajax发送请求–浏览器–服务器 响应过程则是请求过程的颠倒 当ajax发送请求到浏览器,浏览器发送到服务器,处理并响应后,原路返回到浏览器,此时会验证其请求来源的域名跟发送请求时是否一样,是则过,否则会被浏览器截止并提示错误,这正是跨域所造成的,想要解决此问题,并不能从前端入手,应该从后端,只有在后端响应并返回后告诉浏览器是自己人即可。 那怎么告诉浏览器是自己人呢? 只要设置其响应头部信息+(Access-Control-Allow-Origin:域名)告诉浏览器即可,允许多个、单个、全部 (*)。
/*
1、允许单个域名访问
*/
header("Access-Control-Allow-Origin:(域名)");
/*
2、允许多个域名访问
*/
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
$option = array(
('域名1'),
('域名2'),
....
);
if(in_array($origin,$option)) header("Access-Control-Allow-Origin:$origin");
/*
3、允许全部域名访问
*/
header("Access-Control-Allow-Origin:*");
/*
1、允许单个域名访问
*/
http.createServer(req,res)
{
res.setHeader("Access-Control-Allow-Origin","(域名)");
}
/*
2、允许多个域名访问
*/
let option = [
(域名1),
(域名2),
...
];
http.createServer(req,res)
{
let {origin} = req.headers;
let ori = option["origin"] ? option["origin"] : null;
res.setHeader("Access-Control-Allow-Origin",ori);
}
/*
3、允许全部域名访问
*/
http.createServer(req,res)
{
res.setHeader("Access-Control-Allow-Origin","*");
}
FormData是ajax2.0新添加的功能,其作用是让表单也能异步发送
//必须要new 一个FormData对象 参数是要应用的表单元素
//禁止表单默认行为
//其请求方式、请求地址跟随表单元素
//最后发送formdata对象即可
//原生方式
let form = document.querySelector("form");
document.querySelector("form").onsubmit = ()=>{
let xhr = new XMLHttpRequest();
let formdata = new FormData(form);
xhr.open(form.method,form.action,true);
xhr.send(formdata);
xhr.onreadystatechange =()=>{
if(xhr.readyState === 4)
{
if(xhr.status === 200)
{
console.log("成功");
}else
{
console.log("失败");
}
}
}
return false;
}
//jQuery方式
$(function(){
$("form").on("submit",function(){
console.log(1);
let formdata = new FormData(this);
$.ajax({
url:this.action,
type:this.method,
data:formdata,
//由于jq在发送请求时,会把请求数据自动处理为适合发送的数据格式,但是formdata对象本事就不用处理,系统识别会自动处理数据,如果被jq格式化后,数据就会出错,所以要关闭其数据格式化,以及发送的头部信息。
processData:false,
contentType:false
}).then((req)=>{
console.log("成功");
},(res)=>{
console.log("失败");
})
return false;
})
})
//如果不使用表单提交,可以使用以下另门方式
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
用户:<input type="text" id="user" /><br>
密码:<input type="password" id="pass" /><br>
文件:<input type="file" id="f1" /><br>
<input id="btn1" type="button" value="提交">
</div>
</body>
<script>
let oBtn=document.querySelector('#btn1');
oBtn.onclick=function (){
let formdata=new FormData();
formdata.append('username', document.querySelector('#user').value);
formdata.append('password', document.querySelector('#pass').value);
formdata.append('f1', document.querySelector('#f1').files[0]);
//
let xhr=new XMLHttpRequest();
xhr.open('post', 'http://localhost:8080/', true);
xhr.send(formdata);
xhr.onreadystatechange=function (){
if(xhr.readyState==4){
if(xhr.status==200){
alert('成功');
}else{
alert('失败');
}
}
};
};
</script>
</html>
fetch是官方用来解决原生js的ajax的繁杂步骤问题的一门新语法,大大简化了ajax操作,原理基于ajax
// get txt
window.onload=function (){
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.请求
let res=await fetch('data/1.txt');
//2.解析
let str=await res.text();
alert(str);
};
};
//get json
window.onload=function (){
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.请求
let res=await fetch('data/1.json');
//2.解析
let json=await res.json();
console.log(json);
};
};
//get blod
window.onload=function (){
let oImg=document.getElementById('img1');
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.请求
let res=await fetch('data/1.png');
//2.解析
let data=await res.blob();
let url=URL.createObjectURL(data);
oImg.src=url;
};
};