- ajax定义:其实他就是浏览器提供的一套 API,可以通过 JavaScript 调用,从而实现通过代码控制请求与响应。实现 网络编程。
- api的含义,API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。(类似于DOM,浏览器为我们提供这种api,方便我们控制其节点),ajax这种api的作用方便我们进行网络编程。
开始进入ajax的学习
1.1 快速上手(ajax的基本结构)
var xhr = new XMLHttpRequest()#
xhr.open('GET', 'http://day-11.io/time.php')
xhr.send()
xhr.onreadystatechange = function () {
// 这个事件并不是只在响应时触发,XHR 状态改变就触发
// console.log(1)
if (this.readyState !== 4) return
// 获取响应的内容(响应体)
console.log(this.responseText)
}
最新一种事件//onload 是 HTML5 中提供的 XMLHttpRequest v2.0 定义的
xhr.onload = function () {
console.log(this.readyState)
console.log(this.responseText)
}
1.2 readyState
- 对readyState值的解释
readyState | 状态描述 | 说明 |
---|---|---|
0 | UNSENT | 代理(XHR)被创建,但尚未调用 open() 方法 |
1 | OPENED | open() 方法已经被调用,建立了连接 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且已经可以获取状态行和响应头 |
3 | LOADING | 响应体下载中, responseText 属性可能已经包含部分数据 |
4 | DONE | 响应体下载完成,可以直接使用 responseText |
1.3 ajax同样遵循http协议
- 本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求任然是 HTTP 请求,同样符合 HTTP 约定的格式
<script>
var xhr=new XMLHttpRequest();
xhr.open("POST","add.php")
xhr.setRequestHeader("Foo","Bar")//设置一个请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 一旦你的请求体是 urlencoded 格式的内容,一定要设置请求头中 Content-Type 'application/x-www-form-urlencoded'
xhr.send('key1=value1&key2=value2')//以urlencoded格式设置请求体
xhr.onreadystatechange=function(){
if(this.readyState!==4)return
}
1.4 ajax的GET请求实例
- 通常在一次GET请求过程中,参数传递都是通过url地址的?进行传参的
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) } }
// 一般情况下 URL 传递的都是参数性质的数据,而 POST 一般都是业务数据
1.5 ajax的POST请求实例
- 在POST请求中,都是请求体承载所要请求的数据
btn.onclick=function(){
var username=document.getElementById("username").value
var password=document.getElementById("password").value
//获取到两个input里的数据
var xhr=new XMLHttpRequest()
xhr.open("POST","login.php")
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(`username=${username}&password=${password}`)
//将数据传到后台
第二种格式
xhr.send('username=' + username + '&password=' + password)
xhr.onreadystatechange=function(){
if(this.readyState!==4)return
console.log(this.responseText)
1.6 同步和异步
- 同步:通俗的讲,就比如一个人在一段时间。只能做一件事
- 异步:他是在执行一些耗时的事件时不等待,而是去执行其他的事件
xhr.open() 方法第三个参数要求传入的是一个 bool 值,其作用就是设置此次请求是否采用异步方
式执行,默认 为 true ,如果需要同步执行可以通过传递 false 实现:
1.7 响应式数据格式
如果服务器返回的数据是一个复杂的数据,我们该怎么处理
1. XML
一种数据描述手段 老掉牙的东西,简单演示一下,不在这里浪费时间,基本现在的项目不用了。 淘汰的原因:数据冗余太多
2. JSON
也是一种数据描述手段,类似于 JavaScript 字面量方式 。服务器采用JSON格式传递数据,客户端就应该按照JSON格式解析数据
3. 处理响应数据渲染
使用模板引擎 artTemplate链接
- 模板引擎实际上就是一个 API,模板引擎有很多种,使用方式大同小异,目的为了可以更容易的将数据渲染到 HTML中
1.8 兼容方案(只用于面试问题)
XMLHttpRequest 在老版本浏览器(IE5/6)中有兼容问题,可以通过另外一种方式代替
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
1.9 进程和线程
- 进程:通俗点就是运行中的程序
- 线程:cpu中的最小执行单元
ajax第二天
2.1 模板引擎实例
- 首先说明script标签的特点
- 其中的innerHTML永远不会出现在界面上
- 他的type标签如果不是text/javascript 的话,内部的东西是不会作为JavaScript解析的
- 基本套路
- 选择一个模板引擎
- 下载模板引擎的js文件
- 引入到页面中去
- 准备一个模板
- 准备一个数据
- 通过模板引擎js提供的一个方法将模板和数据整合得到渲染结果HTML
- 将渲染结果的HTML设置到默认元素的innerHTML中
<body>
<table id="demo"></table>
<!--
script 标签的特点是
1. innerHTML 永远不会显示在界面上
2. 如果 type 不等于 text/javascript 的话,内部的内容不会作为 JavaScript 执行
-->
//模板
<script id="tmpl" type="text/x-art-template">
{{each comments}}
<!-- each 内部 $value 拿到的是当前被遍历的那个元素 -->
<tr>
<td>{{$value.author}}</td>
<td>{{$value.content}}</td>
<td>{{$value.created}}</td>
</tr>
{{/each}}
</script>
<script src="template-web.js"></script>
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'test.php')
xhr.send()
xhr.onreadystatechange = function () {
if (this.readyState !== 4) return
var res = JSON.parse(this.responseText)
// 模板所需数据
var context = { comments: res.data }
// 借助模板引擎的API 渲染数据
var html = template('tmpl', context)
console.log(html)
document.getElementById('demo').innerHTML = html
// 1. 选择一个模板引擎
// https://github.com/tj/consolidate.js#supported-template-engines
// 2. 下载模板引擎JS文件
// 3. 引入到页面中
// 4. 准备一个模板
// 5. 准备一个数据
// 6. 通过模板引擎的JS提供的一个函数将模板和数据整合得到渲染结果HTML
// 7. 将渲染结果的HTML 设置到 默认元素的 innerHTML 中
// var tmpl = '{{if user}}<h2>{{user.name}}</h2>{{/if}}'
//
// 为什么不在JS变量中写模板?
// 1. 如果将模板写到JS中,维护不方便,不能换行,没有着色
// 为什么使用script标记
// 1. script不会显示在界面
}
</script>
2.2 ajax的封装
- 首先函数就可以理解为一个想要做的事情,函数体中约定了这件事情做的过程,直到调用时才开始工作。 将函数作为参数传递就像是将一个事情交给别人,这就是委托的概念
// 封装者
// =============================
function ajax (method, url, params, done) {
method = method.toUpperCase()
var xhr = new XMLHttpRequest()
if (typeof params === 'object') {
var tempArr = []
for (var key in params) {
var value = params[key]
tempArr.push(key + '=' + value)
}
params = tempArr.join('&')
}
if (method === 'GET') {
url += '?' + params
}
xhr.open(method, url, false)
var data = null
if (method === 'POST') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
data = params
}
xhr.onreadystatechange = function () {
if (this.readyState !== 4) return
// 不应该在封装的函数中主观的处理响应结果
// console.log(this.responseText)
// 你说我太主观,那么你告诉我应该做什么
done(this.responseText)
}
xhr.send(data)
}
// 调用者
// ============================
var onDone = function (res) {
console.log('hahahahaha')
console.log('hohohohoho')
console.log(res)
console.log('做完了')
}
ajax('get', 'time.php', {}, onDone)
2.3 jq中的ajax
参考
- http://www.jquery123.com/category/ajax/
- http://www.w3school.com.cn/jquery/jquery_ref_ajax.asp
最底层
$.ajax({
url: 'json.php',
type: 'get',
// 设置的是请求参数
data: { id: 1, name: '张三' },
// 用于设置响应体的类型 注意 跟 data 参数没关系!!!
dataType: 'json',
success: function (res) {
// 一旦设置的 dataType 选项,就不再关心 服务端 响应的 Content-Type 了
// 客户端会主观认为服务端返回的就是 JSON 格式的字符串
console.log(res)
}
})
常用
$.get('http://locally.uieee.com/categories', function (res) {
console.log(res)
})
常见参数
url:请求地址
type:请求方法,默认为 get
dataType:服务端响应数据类型
contentType:请求体内容类型,默认 application/x-www-form-urlencoded
data:需要传递到服务端的数据,如果 GET 则通过 URL 传递,如果 POST 则通过请求体传递
timeout:请求超时时间
beforeSend:请求发起之前触发
success:请求成功之后触发(响应状态码 200)
error:请求失败触发
complete:请求完成触发(不管成功与否)
2.4 综合应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>text14</title>
<style>
#demo{
width: 500px;
height: 500px;
color: #fff;
background-color: #111;
display: none;
}
</style>
<script src="jq.js"></script>
</head>
<body>
<div id="demo">正在加载</div>
<button id="bu1">登录</button>
<script>
$(document).ajaxStart(function(){
$("#demo").fadeIn()
})
$(document).ajaxStop(function(){
$("#demo").fadeOut()
})
$("#bu1").on("click",function(){
$.get("text.php")
})
</script>
</body>
</html>
2.5 跨域
- 相关概念
- 同源策略是浏览器的一种安全策略,所谓同源是指域名,协议,端口完全相同,只有同源的地址才可以相互通过 AJAX 的方式请求。
- 同源或者不同源说的是两个地址之间的关系,不同源地址之间请求我们称之为跨域请求
解决方案(JSONP)
JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。 其原理就是在客户端借助 script 标签请求服务端的一个动态网页(php 文件),服务端的这个动态网页返回一 段带有函数调用的 JavaScript 全局函数调用的脚本,将原本需要返回给客户端的数据传递进去。
扩展 一 (箭头函数)
代码实例
在我们正常开发是,可能会写到这样的代码
const Person = {
'name': 'little bear',
'age': 18,
'sayHello': function () {
setInterval(function () {
console.log('我叫' + this.name + '我今年' + this.age + '岁!')
}, 1000)
}
}
Person.sayHello()
但是,如果细心观察的话便会发现。他是肯定不会按照我们的想法来输出的,他的输出结果应为undefined
原因setInterval执行的时候,是在全局作用域下的,所有this指向的是全局window,而window上没有name和age,所以当然输出的是undefined