Ajax个人笔记

AJAX

概述

A JAX(Asynchronous JavaScript and XML(异步的 JavaScript 和 XML) ),最早出现在 2005 年的 Google Suggest,是在浏览器端进行网络编 程(发送请求、接收响应)的技术方案,它使我们可以通过 JavaScript 直接获取服务端最新的内容而不必重新加载 页面。让 Web 更能接近桌面应用的用户体验。

A JAX 就是浏览器提供的一套 API,可以通过 JavaScript 调用,从而实现通过代码控制请求与响应。实现网络编程。

开发时注意:涉及到AJAX操作的页面“不能”使用文件协议访问(file://),因为不同源,但JSONP可以。

参考http://www.runoob.com/ajax/ajax-xmlhttprequest-create.html

快速上手

// 1. 创建一个 XMLHttpRequest 类型的对象 —— 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 4. 指定 xhr 状态变化事件处理函数 —— 相当于处理网页呈现后的操作
xhr.onreadystatechange = function () {
    // 通过 xhr 的 readyState 判断此次请求的响应是否接收完成
    if (this.readyState === 4) {
    // 通过 xhr 的 responseText 获取到响应的响应体
    console.log(this);
    }
// 2. 打开与一个网址之间的连接 —— 相当于在地址栏输入访问地址
xhr.open('GET', './time.php');
// 3. 通过连接发送一次请求 —— 相当于回车或者点击访问发送请求
xhr.send(null);
}

创建 XMLHttpRequest 对象(重点)

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用ActiveXObject)。

var xmlhttp;
if (window.XMLHttpRequest) {
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xmlhttp=new XMLHttpRequest();
} else {
    // IE6, IE5 浏览器执行代码
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

向服务器发送请求(重点)

xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
方法描述
open(method,url,async)规定请求的类型、URL 以及是否异步处理请求。method:请求的类型;GET 或 POST。 url:文件在服务器上的位置。 async:true(异步,推荐)或 false(同步, 请不要编写 onreadystatechange 函数,把代码放到 send() 语句后面即可)。
send(string)将请求发送到服务器。 string:仅用于 POST 请求。

readyState(理解)

onreadystatechange 事件

onreadystatechange事件含有readyState属性和status属性。

由于 readystatechange 事件是在 xhr 对象状态变化时触发(不单是在得到响应时),也就意味着这个事件会被触发多次。

readyState状态描述说明
0UNSENT代理(XHR)被创建,但尚未调用open()方法。
1OPENEDopen()方法已经被调用,建立了连接。
2HEADERS_RECEIVEDsend()方已经调用,并且已经可以获取状态行和响应头。
3LOADING响应体下载中,responseText属性可能已经包含部分数据。
4DONE响应体下载完成,可以直接使用responseText
status描述
200“OK”
404未找到页面

在这里插入图片描述

响应(遵循HTTP)

本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求任然是 HTTP 请求,同样符合 HTTP 约定的格式:

PS:xhr.onload是readyState === 4的执行过程。

// 设置请求报文的请求行
xhr.open('GET', './time.php')
// 设置请求头
xhr.setRequestHeader('Accept', 'text/plain')
// 设置请求体
xhr.send(null)
xhr.onreadystatechange = function () {
    if (this.readyState === 4) {
        // 获取响应状态码
        console.log(this.status)
        // 获取响应状态描述
        console.log(this.statusText)
        // 获取响应头信息
        console.log(this.getResponseHeader('Content‐Type')) // 指定响应头
        console.log(this.getAllResponseHeaders()) // 全部响应头
        // 获取响应体
        console.log(this.responseText) // 文本形式
        console.log(this.responseXML) // XML 形式,了解即可不用了
    }
}
属性描述
status响应状态码
statusText响应状态描述
getResponseHeader()获取指定响应头
getAllResponseHeader()获取全部响应头
responseText获得字符串形式的响应数据(响应体)。
responseXML获得 XML 形式的响应数据(响应体)。
response获取的结果会根据this.responseType的变化而变化。默认与responseText一样。(HTML5新属性)
responseType设置请求代理对象。

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

GET请求(重点)

通常在一次GET请求中,参数传递都是通过URL地址中的?参数传递

一般情况下 URL 传递的都是参数性质的数据,而 POST 一般都是业务数据。

var xhr = new XMLHttpRequest();
// GET 请求传递参数通常使用的是问号传参
// 这里可以在请求地址后面加上参数,从而传递数据到服务端
xhr.open('GET', './delete.php?id=1');
// 一般在 GET 请求时无需设置响应体,可以传 null 或者干脆不传
xhr.send(null);
xhr.onreadystatechange = function () {
   if (this.readyState === 4) {
       console.log(this.responseText);
   }
}

POST请求(重点)

POST请求过程中,都是采用请求体承载需要提交的数据。

  • setRequestHeader():设置一个请求头。
  • send(string):将string发送给服务器。

ps:

  1. 请求头中的contype-type对应html中设置的entype属性。注意传数据给服务器的数据格式的不同,要设置请求头中对应的Content-type。
  2. post请求利用send()传递参数。
var xhr = new XMLHttpRequest();
// open 方法的第一个参数的作用就是设置请求的 method
xhr.open('POST', './add.php');
// 设置请求头中的 Content‐Type 为 application/x‐www‐form‐urlencoded
// 标识此次请求的请求体格式为 urlencoded 以便于服务端接收数据
xhr.setRequestHeader('Content‐Type', 'application/x‐www‐form‐urlencoded');
// 需要提交到服务端的数据可以通过 send 方法的参数传递
// 格式:key1=value1&key2=value2
xhr.send('key1=value1&key2=value2');
xhr.onreadystatechange = function () {
    if (this.readyState === 4) {
         console.log(this.responseText);
    }
}

同步与异步(推荐异步)

xhr.open()方法第三个参数要求传入的是一个 bool 值,其作用就是设置此次请求是否采用异步方式执行,默认 为 true ,如果需要同步执行可以通过传递 false 实现。如果采用同步方式执行,则代码会卡死在 xhr.send() 这一步。

响应数据格式

不管服务端是采用XML还是采用JSON本质上都是将数据返回给客户端

服务端一个设置一个合理的Content-Type(Content-Type: application/xml或application/json等)。

XML

一种数据描述手段,基本现在的项目不用了,客户端解析服务端返回的xml文件类似于DOM那样 。 淘汰的原因:数据冗余太多 。

var xhr = new XMLHttpRequest();
xhr.open('GET','xml.php');
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState != 4)
    return;
console.log(this.responseXML.documentElement.children[0].innerHTML);
console.log(this.responseXML.documentElement.getElementsByTagName('name')[0].innerHTML);
}
JSON

也是一种数据描述手段,类似于 JavaScript 字面量方式 服务端采用 JSON 格式返回数据,客户端按照 JSON 格式解析数据。

处理响应数据渲染

模板引擎:

模板引擎实际上就是一个 API,模板引擎有很多种,使用方式大同小异,目的为了可以更容易的将数据渲染到 HTML中。

script标签如果type不等于text/javascript的话,内部内容不会作为JavaScript执行。

一般使用模板引擎,把script标签的type设为text/x-模板引擎名。

封装

AJAX请求封装

/**
* 发送一个 AJAX 请求
* @param {String} method 请求方法
* @param {String} url 请求地址
* @param {Object} params 请求参数
* @param {Function} done 请求完成过后需要做的事情(委托/回调)
*/
function ajax (method, url, params, done) {
    // 统一转换为大写便于后续判断
    method = method.toUpperCase();
    // 对象形式的参数转换为 urlencoded 格式
    var pairs = [];
    for (var key in params) {
         pairs.push(key + '=' + params[key]);
    } 
    var querystring = pairs.join('&');
    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new
ActiveXObject('Microsoft.XMLHTTP');
    xhr.addEventListener('readystatechange', function () {
        if (this.readyState !== 4) return;
        // 尝试通过 JSON 格式解析响应体
        try {
             done(JSON.parse(this.responseText));
        } catch (e) {
             done(this.responseText);
        }
    });
    // 如果是 GET 请求就设置 URL 地址 问号参数
    if (method === 'GET') {
        url += '?' + querystring;
    } 
    xhr.open(method, url);
    // 如果是 POST 请求就设置请求体
    var data = null;
    if (method === 'POST') {
        xhr.setRequestHeader('Content‐Type', 'application/x‐www‐form-urlencoded');
        data = querystring;
    } 
    xhr.send(data);
}

jQuery中的AJAX(重点)

参考:

$.ajax()(底层接口)

ajax() 方法通过 执行HTTP 请求加载远程数据。
. a j a x ( ) 返 回 其 创 建 的 X M L H t t p R e q u e s t 对 象 。 ∗ ∗ 语 法 : ‘ .ajax() 返回其创建的 XMLHttpRequest 对象。 **语法:` .ajax()XMLHttpRequest.ajax(url[, settings]);`**

  • url:一个用来包含发送请求的URL字符串。
  • settings:一个以"{键:值}"组成的AJAX 请求设置。所有选项都是可选的。可以使用$.ajaxSetup()设置任何默认参数。

常用选项参数介绍:

  • url:请求地址。
  • type:请求方法,默认为 get。
  • dataType:服务端响应数据类型。
  • contentType:请求体内容类型,默认application/x-www-form-urlencoded
  • data:需要传递到服务端的数据,如果GET则通过URL传递,如果POST则通过请求体传递。
  • timeout:请求超时时间。
  • beforeSend:请求发起之前触发(open()之前)。
  • success:请求成功之后触发(响应状态码200)。
  • error:请求失败触发。返回的是对象。
  • complete:请求完成触发(不管成功与否)。
$.ajax({
    url: 'get.php', // 请求地址
    type: 'get', // method请求方法
    data: {id: 1}, // 传递参数
    dataType: 'json', // 预期服务器返回的数据类型。用于设置响应体的类型(ContentType)。
    beforeSend: function (xhr) {
        console.log('before send');
    }, // 请求发起之前触发,即在open()之前。
    success: function (res) {
        console.log(res);
    }, // 请求成功拿到的只是响应体,就是readyState=4后的执行函数;会根据Content-Type自动转换res。
    error: function (err) {
        console.log(err);
    }, // 请求失败触发。
    complete: function () {
        console.log('request completed');
    } // 不管成功与否,请求完成触发。
});
$.get()(重要,与$.post()语法一样)

GET 方法可能返回缓存数据。
**$.get() 方法通过 HTTP GET 请求从服务器上请求数据。 **
语法:$.get(URL,data,callback);

$.post()(重要)

POST 方法不会缓存数据,并且常用于连同请求一起发送数据。
**$.post() 方法通过 HTTP POST 请求从服务器上请求数据。 **
语法:$.post(URL,data,callback);

  • URL:请求的 URL。
  • data:连同请求发送的数据。 即传送的参数。
  • callback:请求成功后所执行的函数名。 第一个回调参数存有被请求页面的内容,而第二个参数存有请求的状态。
$("button").click(function(){
  $.post("demo_test_post.asp",
  {
    name:"Donald Duck",
    city:"Duckburg"
  },
  function(data,status){
    alert("Data: " + data + "\nStatus: " + status);
  });
});
了解
  • $(selector).load(url[,data][,complete(data,status,xhr)])
    • **通过 AJAX 请求从服务器加载数据,并把返回的数据放置到指定的元素中。 **
    • complete:请求完成时执行的回调函数。
  • $.getJSON(url[,data][,success(data,status,xhr)])
    • 通过 HTTP GET 请求载入 JSON 数据。 即等价于使用$.ajax()且dataType设置为json。
    • url:请求的URL字符串,即地址。
    • data:发送给服务器的字符串或Key/value键值对。即参数
    • success:当请求成功后执行的回调函数。 response 包含来自请求的结果数据,status 包含请求的状态,xhr 包含 XMLHttpRequest 对象。
  • $.getScript(url[,success(script,status,xhr)])
    • **通过 HTTP GET 请求载入并执行 JavaScript 文件。**即等价于使用$.ajax()且dataType设置为JavaScript。
  • .ajaxStart(handler())
    • 在AJAX 请求刚开始时执行一个处理函数。
  • .ajaxStop(handler())
    • 在AJAX 请求完成时执行一个处理函数。

跨域(重要)

同源策略

同源策略是浏览器的一种安全策略,所谓同源是指域名,协议,端口完全相同,只有同源的地址才可以相互通过 A JAX 的方式请求。 **
同源或者不同源说的是两个地址之间的关系,不同源地址之间请求称为
跨域请求 **。
什么是同源?例如:http://www.example.com/detail.html 与一下地址对比

对比地址是否同源原因
http://api.example.com/detail.html不同源域名不同
https://www.example.com/detail.html不同源协议不同
http://www.example.com:8080/detail.html不同源端口不同
http://api.example.com:8080/detail.html不同源域名、端口不同
https://api.example.com/detail.html不同源协议、域名不同
https://www.example.com:8080/detail.html不同源端口、协议不同
http://www.example.com/other.html同源只是目录不同

解决跨域请求

JSONP(常用)

JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。

其原理就是在客户端借助**<script> 标签请求服务端的一个动态网页(php 文件),服务端的这个动态网页返回一段带有函数调用的 JavaScript 全局函数调用的脚本**(header(contentType: application/javascript)),将原本需要返回给客户端的数据传递进去。

例:(jsonp封装)

注意:可能请求有很多次的时候,若都是调用同一函数名会发生覆盖问题,因此要生成多个唯一函数名。

function jsonp(url, params, callback){
    var script = document.createElement('script');
    // 生成唯一函数名
    var funcName = 'jsonp_' + Date.now() + Math.random().toString().substr(2);
    window[funcName] = function(data) {
        callback(data);
        delete window[funcName];
        document.body.removechild(script);
    }
    // 添加参数
    if(typeof params === 'object'){
        var tempArr = [];
        for(var key in params){
            var value = params[key];
            tempArr.push(key + '=' + value);
        }
        params = tempArr.join('&');
    }
    // 请求不同源地址
    script.src = url + '?' + params + '&callback' + funcName;
    document.body.appendChild(script);
}
<?
  $conn = mysqli_connect('localhos','root','123456','demo');
  $query = mysqli_query($conn, 'select * from users');
  while ($row = mysqli_fetch_assoc($query)) {
    $data[] = $row;  
  }
  if(empty($_GET['callback'])){
      header('Content-Type: application/json');
      echo json_encode($data);
      exit();
  }
  header('Conntent-Type: application/javascript');
  $result = json_encode($data);
  // 判断客户端给过来的是否为函数
  $callback_name = $_GET['callback'];
  echo "typeof {$callback_name} === 'function' && {$callback_name}({$result})";
?>

问题:

  1. JSONP 需要服务端配合,服务端按照客户端的要求返回一段 JavaScript 调用客户端的函数。
  2. 只能发送 GET 请求。

注意:JSONP 用的是 script 标签,跟A JAX 提供的 XMLHttpRequest 没有任何关系!!!

jQuery使用JSONP

jQuery 中使用 JSONP 就是将 dataType 设置为 jsonp。

$.ajax({
    url: '请求不同源地址',
    dataType: 'jsonp',
    data: {传递参数},
    success: function(res){
        console.log(res);
    }
});

其他常见的 A JAX 封装库:

  • Axios
CORS

Cross Origin Resource Share,跨域资源共享。

// 允许远端访问,*可以是其他源
header('Access‐Control‐Allow‐Origin: *');

这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个Access Control-Allow-Origin的响应头,表示这个资源是否允许指定域请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值