首页
学习
活动
专区
工具
TVP
发布

Ajax

作者头像
jinghong
发布2020-05-09 15:27:42
5.9K0
发布2020-05-09 15:27:42
举报

什么是Ajax?

Ajax是一种可以与服务器交换数据并更新部分页面内容,同时可以在不让整个网页重新加载的情况下更新网页的一种技术

Ajax请求过程:

1:创建一个异步对象
var xmlHttp = new XMLHttpRequest();
2:设置请求方式和请求地址
/*
    参数顺序,描述
    (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")
3:发送请求
 xmlHttp.send();
4.监听状态变化
//监听事件: 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('请求失败')
                }
    }



}

http请求成功或失败状态码资料查询

IE低版本浏览器兼容问题

由于在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");

封装Ajax

/**
 * @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("请求失败");
                    },

                });

获取服务器响应数据方式

  1. responseText 可以获取服务器以字符串形式返回的数据
  2. responseXML 可以获取服务器以XML形式返回的数据
//调用方式
// ajax对象.要获取的方式
xmlHttp.responseText

通过XML传输数据

XML数据基本格式

​ 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基本XML配置格式
<?php
    //向客户端发送原始的 HTTP 报头。
    header("content-type:text/xml;charset=utf-8");
    //file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用    内存映射技术来增强性能。
    echo file_get_contents("xml文件地址如(./ajax.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);

通过JSON传输数据

JSON资料

JSON数据基本格式
{
    "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对象转换为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转js对象
//当从服务器返回的数据不是标准json字符串时是无法使用parse的,那么可以试试用eval()强制转化和为js对象
//注意点: 转js对象必须加 "("+data+")"
var Data = eval("("+data+")")
JSON兼容性问题

在低版本的IE中, 不可以使用原生的JSON.parse方法, 但是可以使用json2.js这个框架来兼容 json2.js下载地址:

PHP基本JSON格式
echo file_get_contents(" JSON文件地址 如(./json.txt)");

跨域

ajax的请求过程:ajax发送请求–浏览器–服务器 响应过程则是请求过程的颠倒 当ajax发送请求到浏览器,浏览器发送到服务器,处理并响应后,原路返回到浏览器,此时会验证其请求来源的域名跟发送请求时是否一样,是则过,否则会被浏览器截止并提示错误,这正是跨域所造成的,想要解决此问题,并不能从前端入手,应该从后端,只有在后端响应并返回后告诉浏览器是自己人即可。 那怎么告诉浏览器是自己人呢? 只要设置其响应头部信息+(Access-Control-Allow-Origin:域名)告诉浏览器即可,允许多个、单个、全部 (*)。

PHP 方式

/*
    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:*");

node方式

/*
    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

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

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;
      };
    };
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是Ajax?
    • Ajax请求过程:
      • IE低版本浏览器兼容问题
        • 解决兼容性通用方法
          • 封装Ajax
            • 获取服务器响应数据方式
              • 通过XML传输数据
                • 通过JSON传输数据
                  • 跨域
                    • PHP 方式
                    • node方式
                  • FormData
                    • 语法格式:
                  • fetch
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档