1.入门
主要掌握:
json数据转换
简单的封装,创建流程
能够使用、读懂别人写的封装,jq的封装使用
跨域概念
注:本文的所有Ajax操作都是在WampServer的www目录下启动的
1.1 简介
AJAX = Asynchronous JavaScript And XML.
AJAX 并非编程语言。
主要为了创建更快、更好的web程序
优点:常用于局部刷新
官方文档:https://www.w3school.com.cn/js/js_ajax_intro.asp
同步异步:
同步是指:当程序1调用程序2时,程序1停下不动,直到程序2完成回到程序1来,程序1才继续执行下去。
异步是指:当程序1调用程序2时,程序1径自继续自己的下一个动作,不受程序2的的影响。
1.2 Ajax能干嘛
- 不刷新页面更新网页
- 在页面加载后从服务器请求数据
- 在页面加载后从服务器接收数据
- 在后台向服务器发送数据
1.3 JSON的转换
var json=[
{
name:'雷军',
attr:'雷属性',
address:'稻妻'
},
{
name:'温迪',
attr:'风属性',
address:'蒙德'
},
{
name:'钟离',
attr:'岩属性',
address:'璃月'
},
]
方法一:(推荐)
var arr=JSON.stringify(json)//将json对象转为字符串
var arr=JSON.parse(arr)//将json字符串转为json数组对象
console.log(arr)
JSON.stringify(obj,arr)
第二个参数为过滤字段
//过滤
var str =JSON.stringify(json,['name'])
console.log((str)
方法二:(不推荐)
//eval() 不推荐
var arr=eval(json)
console.log(arr)
2 Ajax创建
ajax请求的过程:
1、创建ajax对象 XMLHttpRequest 或者 IE采用activeXObject
2、发起http请求 get/post open() send()
3、监听状态改变 onreadystatechange监听readyState status
4、接收服务器响应的数据 responseText
5、渲染页面
2.0监听状态码
onreadystatechange 当readyState发生改变则自动调用
readState 为服务器的状态信息
0 | 请求未初始化(在调用 open() 之前) |
---|---|
1 | 请求已提出(调用 send() 之前) |
2 | 请求已发送(这里通常可以从响应得到内容头部) |
3 | 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应) |
4 | 请求已完成(可以访问服务器响应并使用它) |
常见的http状态码:https://www.cnblogs.com/xflonga/p/9368993.html
200:OK
304:not modified
400:错误请求(bad request)
401:未授权(unauthorized)
403:禁止(forbidden)
404:not found
500:服务器出错
2.1get方法
// 1、创建ajax对象
function Ajax(){
var ajax;
if(window.XMLHttpRequest){
try{
ajax=new XMLHttpRequest();
}catch(err){
console.error(err)
}
}
else if(window.ActiveXObject){
try{
var version = [
'Microsoft.XMLHTTP',
'MSXML.XMLHTTP',
'MSXML2.XMLHTTP.3.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.7.0'
]
for(var i=0;i<version.length;i++){
ajax=new ActiveXObject(version[i])
}
ajax=new ActiveXObject()
}catch(err){
console.error(err)
}
}
return ajax;
}
//3、监听状态改变
var btn=document.querySelector('button')
btn.onclick=function(){
var ajax=Ajax()
// var data
console.log(ajax)
ajax.onreadystatechange=function(){
if(ajax.readyState==4 && ajax.status==200){
//4,接收服务器响应的数据
var data=JSON.parse(ajax.responseText)
console.log(data)//查看有没有给服务器传值成功
}
}
//2、发起http请求数据get
//open(请求类型,URL地址,true)
//send()发送请求数据到服务器 get请求的数据直接写在url之后
ajax.open('get','getData.php?name=key',true)
//get请求必须有send()方法,send内写为null
ajax.send(null)
}
<?php
// 获取get请求传递的数据
// var_dump($_GET)
//后端只要有输出则为响应的数据
// echo '111';
// echo '服务器端数据';
//json_encode()将数组转换为json字符串
echo json_encode($_GET);
?>
2.2post方法
常见的四种post提交数据的content-type的类型
https://www.cnblogs.com/wushifeng/p/6707248.html
方法一:
// 1、创建ajax对象
function Ajax(){
var ajax;
if(window.XMLHttpRequest){
try{
ajax=new XMLHttpRequest();
}catch(err){
console.error(err)
}
}
else if(window.ActiveXObject){
try{
var version = [
'Microsoft.XMLHTTP',
'MSXML.XMLHTTP',
'MSXML2.XMLHTTP.3.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.7.0'
]
for(var i=0;i<version.length;i++){
ajax=new ActiveXObject(version[i])
}
ajax=new ActiveXObject()
}catch(err){
console.error(err)
}
}
return ajax;
}
//3、监听状态改变
var btn=document.querySelector('button')
btn.onclick=function(){
var ajax=Ajax()
// var data
console.log(ajax)
ajax.onreadystatechange=function(){
if(ajax.readyState==4 && ajax.status==200){
//4,接收服务器响应的数据
var data=JSON.parse(ajax.responseText)
console.log(data)//查看有没有给服务器传值成功
}
}
//2、发起http请求数据post
ajax.open('POST','postData.php',true)
ajax.setRequestHeader('content-type','application/x-www-form-urlencoded')
ajax.send('name=zhangsan&age=18')
}
<?php
echo json_encode($_POST);
?>
方法二:
// 1、创建ajax对象
function Ajax(){
var ajax;
if(window.XMLHttpRequest){
try{
ajax=new XMLHttpRequest();
}catch(err){
console.error(err)
}
}
else if(window.ActiveXObject){
try{
var version = [
'Microsoft.XMLHTTP',
'MSXML.XMLHTTP',
'MSXML2.XMLHTTP.3.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.7.0'
]
for(var i=0;i<version.length;i++){
ajax=new ActiveXObject(version[i])
}
ajax=new ActiveXObject()
}catch(err){
console.error(err)
}
}
return ajax;
}
//3、监听状态改变
var btn=document.querySelector('button')
btn.onclick=function(){
var ajax=Ajax()
// var data
console.log(ajax)
ajax.onreadystatechange=function(){
if(ajax.readyState==4 && ajax.status==200){
//4,接收服务器响应的数据
var data=JSON.parse(ajax.responseText)
console.log(data)//查看有没有给服务器传值成功
}
}
//2、发起http请求数据post
ajax.open('POST','postData.php',true)
ajax.setRequestHeader('content-type','application/json')
var data=[{name:'zhangsan',age:12}]
ajax.send(JSON.stringify(data))
}
可以看到这种方式响应的数据没有直接获取到,但是在Headers下,我们已经传输成功了,这时需要后端人员自己来得到我们传过去的数据。
2.3get,post?
GET 比 POST 更简单更快,可用于大多数情况下。
不过,请在以下情况始终使用 POST:
-
缓存文件不是选项(更新服务器上的文件或数据库)
-
向服务器发送大量数据(POST 无大小限制)
-
发送用户输入(可包含未知字符),POST 比 GET 更强大更安全
-
get的数据可以直接在url中查看,post不能看到
-
get数据有大小限制,post没有大小限制
-
get不安全,post安全
在ajax中:
- post的数据是在send里面发送的,get的数据是在open的第二个参数url地址里发送的
- post还多了一个setRequestHeader请求头部
3,封装ajax
function Ajax(getType){
//创建一个新变量
var ajax = new Object();
//判断传递进来的文件类型
ajax.getType = getType ? getType.toUpperCase() : 'HTML';
ajax.url = '';//url地址
ajax.sendContent = '';//发送过来的数据
// 创建ajax对象
ajax.getXMLHttpRequest = function(){
//1.自定义局部变量ajax对象
var aj = false;
//分两种情况获取
//1.非IE(除了IE7和IE8)
if(window.XMLHttpRequest){
//获取ajax对象
aj = new XMLHttpRequest();
//判断 对部分mozillar浏览器的BUG进行修正
if(aj.overrideMimeType){
aj.overrideMimeType('text/xml');
}
//IE
}else if(window.ActiveXObject){
//区分不同版本IE浏览器
var versons = [
'Microsoft.XMLHTTP',
'MSXML.XMLHTTP',
'MSXML2.XMLHTTP.3.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.7.0'
];
//遍历数组
for(var i=0;i<versons.length;i++){
try{
aj = new ActiveXObject(versons[i]);
if(aj){
return aj;
}
}catch(e){
aj = false;
}
}
}
return aj;
};
ajax.resHandle = '';//回调函数
//获取ajax的XMLHttpRequest对象
ajax.XMLHttpRequest = ajax.getXMLHttpRequest();
//封装ajax的get方法
ajax.get = function(url,sendContent,resHandle){
//将实参赋值给自定义的ajax对象的url属性
ajax.url = url;
// sendContent {name:'1223',age:10}
// 处理发送过来的信息
if(typeof sendContent == 'object'){
var str = '';
for(var i in sendContent){
str += i+'='+sendContent[i]+'&';//name=ccc&age=20
// console.log(i);
// console.log(sendContent[i]);
}
// console.log(str);
// 去除多余的&
ajax.url = url+'?'+str.substr(0,str.length-1);
}else{
ajax.url = url+'?'+sendContent;
}
//判断resHandle是否为空
if(resHandle != null){
//将回调函数赋值给全局变量并且使用内部函数去处理
// ajax.XMLHttpRequest.onreadystatechange = function(){
// //判断状态值
// if(ajax.XMLHttpRequest.readyState == 4){
// if(ajax.XMLHttpRequest.status == 200){
// if(ajax.getType == 'HTML'){
// //响应ajax 调用reshandle
// ajax.resHandle(ajax.XMLHttpRequest.responseText);
// }
// }
// }
// };
ajax.XMLHttpRequest.onreadystatechange = ajax.doHandle;
// 将传入的回调函数赋值给全局变量ajax.resHandle
ajax.resHandle = resHandle;
}
if(window.XMLHttpRequest){
ajax.XMLHttpRequest.open("get",ajax.url);
ajax.XMLHttpRequest.send(null);
}else{
ajax.XMLHttpRequest.open("get",ajax.url,true);
ajax.XMLHttpRequest.send();
}
};
//处理ajax监听事件
ajax.doHandle = function(){
//判断状态值
if(ajax.XMLHttpRequest.readyState == 4){
if(ajax.XMLHttpRequest.status == 200){
if(ajax.getType == 'HTML'){
//响应ajax 调用reshandle
ajax.resHandle(ajax.XMLHttpRequest.responseText);
}
}
}
};
//封装post
ajax.post = function(url,sendContent,resHandle){
//将实参赋值给变量
ajax.url = url;
//判断sendContent是否是对象
if(typeof sendContent == 'object'){
//是对象
var str = '';
//遍历对象 for(var 变量 in obj){} {name:'sss',age:40}
for(var i in sendContent){
//变成对象形式的字符串
// alert(i+sendContent[i]);
str += i+'='+sendContent[i]+'&'
// str+=i+"="+sendContent[i]+"&"; // name=aaa&age=19&
}
//去掉最后一个多余的"&" substr(开始下标,截取个数)从开始下标开始截取,截取指定的个数 lastIndexOf() slice(start,end)
ajax.sendContent = str.substr(0,str.length-1);
}else{
//不是对象
ajax.sendContent = sendContent;
}
//处理回调函数
//判断回调函数是否为空
if(resHandle != null){
//处理监听事件
ajax.XMLHttpRequest.onreadystatechange = ajax.doHandle;
//将用户传递过来的回调函数交给全局属性
ajax.resHandle = resHandle;
}
//处理ajax的请求
ajax.XMLHttpRequest.open("post",url,true);
ajax.XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajax.XMLHttpRequest.send(ajax.sendContent);
};
return ajax;
}
// var ajax = new Ajax();
// console.log(ajax);
// ajax.post("a.php","username=kuikui&age=18",function(data){
// alert(data);
// });
// ajax.post("a.php",{username:"maimai",age:22},function(data){
// alert(data);
// });
测试:
<script src="ajax.js"></script>
<script>
var ajax=new Ajax()
// ajax.get('getData.php','name=cdd&sex=boy',function(data){
// console.log(data)
// })
// ajax.get('getData.php',{name:'胡桃',sex:'女'},function(data){
// var data=JSON.parse(data)
// console.log(data)
// })
ajax.post('postData.php',{name:'胡桃',sex:'女'},function(data){
var data=JSON.parse(data)
console.log(data)
})
)
</script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sdti0Okf-1630553134803)(C:%5CUsers%5Ccdd%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210901191434445.png)]
4,从本地json文件中获取数据
wearth.json
{"desc":"OK","status":1000,"data":{"wendu":"22","ganmao":"风较大,较易发生感冒,注意防护。","forecast":[{"fengxiang":"北风","fengli":"5-6级","high":"高温 24℃","type":"晴","low":"低温 11℃","date":"3日星期六"},{"fengxiang":"北风","fengli":"4-5级","high":"高温 19℃","type":"晴","low":"低温 8℃","date":"4日星期日"},{"fengxiang":"无持续风向","fengli":"微风","high":"高温 21℃","type":"晴","low":"低温 9℃","date":"5日星期一"},{"fengxiang":"无持续风向","fengli":"微风","high":"高温 21℃","type":"多云","low":"低温 10℃","date":"6日星期二"},{"fengxiang":"无持续风向","fengli":"微风","high":"高温 24℃","type":"晴","low":"低温 12℃","date":"7日星期三"},{"fengxiang":"无持续风向","fengli":"微风","high":"高温 23℃","type":"晴","low":"低温 11℃","date":"8日星期四"}]}}
*{
padding: 0;
margin: 0;
}
.box{
width: 1000px;
height: 700px;
margin: 0 auto;
}
.current{
font-size: 18px;
}
.current p{
font-size: 16px;
}
.forecast{
font-size: 18px;
}
.w_content{
width: 1000px;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: center;
}
.w_content div{
width: 300px;
height: 200px;
margin: 10px 0;
background-color: #fff;
box-shadow: 1px 2px 30px rgb(0, 0, 0,0.1);
}
<div class="box">
<div class="current">
今日天气<p><span>22</span>℃</p><p></p></div>
<div class="forecast">
<div class="head">未来天气</div>
<div class="w_content">
</div>
</div>
</div>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
$.ajax({
url:"wearth.json",
type:'get',
data:{
},//请求时传递到服务器的数据
async:true,//是否异步发送 可以省略,默认值为true
dataType:'json',//服务器返回的数据类型 jsonp常用作跨域
success:function(data){
$('.box .current p').eq(1).html(data.data.wendu)
$('.box .current p:last-child').html(data.data.ganmao)
// 给未来天气追加信息
for(var i=0;i<data.data.forecast.length;i++){
$('.w_content').append("<div><p>"+data.data.forecast[i].date+"</p><p>"+data.data.forecast[i].fengli+"</p><p>"+data.data.forecast[i].fengxiang+"</p><p>"+data.data.forecast[i].high+"</p><p>"+data.data.forecast[i].low+"</p><p>"+data.data.forecast[i].type+"</p></div>")
}
}
})
})
</script>
5,跨域
5.1概念
从一个域访问另外一个域的内容。
不同的域的定义:只要有一个不一样就是不同的域
协议(http/https)域名(主域名 子域名) 端口号
http/https?
- http连接简单,明文传输,https的安全等级高些,通过ssl/tls加密传输、身份认证。
- https协议需要到ca申请证书,需要一定费用。
- 端口不同,http 80端口,https 443端口。
同源策略
当游览器访问存在跨域时,游览器会对其进行限制,该限制叫做同源策略。
5.2方式
1.原生js通过动态创建script标签,获取数据
var tag =document.createElement('script')
tag.src='请求的url地址&callback=callbackfun'
function callbackfun(data){
console.log(data)
}
eg:
<button>点我一下</button>
var btn=document.querySelector('button')
var head=document.querySelector('head')
btn.onclick=function(){
var tag=document.createElement('script')
head.appendChild(tag)
tag.src='http://v.juhe.cn/joke/content/list.php?你的APIkeyid &page=2&pagesize=10&sort=asc&time=1418745237&callback=callbackfun'
}
function callbackfun(data){
console.log(data)
}
2.采用jQuery中使用jsonp来跨域
<script src="jquery-3.5.1.min.js"></script>
<script>
$(function(){
$.ajax({
url:'http://v.juhe.cn/joke/content/list.php',
type:'get',
data:{
key:'你的API keyid',
page:2,
pagesize:5,
sort:'asc',
time:1418745237
},
dataType:'jsonp',
success:function(data){
console.log(data)
},
error:function(err){
console.error(err)
}
})
})
</script>