一,ajax
1.ajax
什么是 ajax?
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
ajax 能极大地提升用户体验,在开发中经常使用!
同步和异步
在了解 ajax 之前首先要明白两个概念:
- 同步: 前端发请求, 必须等到后端响应完成,才允许发送另一个请求
- 异步: 前端发请求后不等待后端响应结果继续执行,后端响应完成通过事件通知前端处理
比如李二狗在房间烧水。
同步:在水烧开之前李二狗啥也不做就目不转睛的盯着水壶等它烧开。
异步:水烧开前李二狗顺便把地拖了一遍,还把碗也洗干净了。等水烧开发出‘呜呜’的声音,二狗便知道已经烧开了,可以过来把它提走。
XMLHttpRequest
XMLHttpRequest 是一个浏览器接口,使得 Javascript 可以进行 HTTP(S)通信。
最早,微软在 IE 5 引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax 操作因此得以诞生。
XMLHttpRequest 对象的主要属性:
- xhr.readyState:XMLHttpRequest 对象的状态,等于 4 表示数据已经接收完毕。
- xhr.status:服务器返回的状态码,等于 200 表示一切正常。
- xhr.responseText:服务器返回的文本数据
- xhr.responseXML:服务器返回的 XML 格式的数据
- xhr.statusText:服务器返回的状态文本。
这个对象是浏览器提供的,是处理异步请求的宿主对象,而非 JS 内置对象
想了解这个对象的详情请点击:http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html
2.ajax 请求方式
ajax 的 http 请求方式有两种:POST 和 GET。
2.1 GET 方式
请求流程:
a. 创建请求对象:new XMLHttpRequest()
b. 监听请求回调:onreadystatechange
c. 初始化请求参数:open(请求类型,请求地址,是否异步)
d. 发送请求:send()
响应:
a. 服务器: 返回JSON
b. 前端:JSON.parse()
解析 JSON 字符串
- JS 代码
// dom 获取按钮
let btn = document.querySelector("button");
// console.log(btn);
// 点击按钮发送请求
btn.addEventListener("click", request, false);
//建立ajax句柄
const getHandle = new XMLHttpRequest();
// 监听readystate 状态,用onreadystatechange方法监听
getHandle.addEventListener("readystatechange", show, false);
//设定请求方式;get|post
getHandle.open("GET", "test1.php", true);
// 点击按钮请求回调
function request(ev) {
//发送ajax请求
// getHandle.send();
// 为了兼容一些老版的浏览器最好在方法里面加上个null
getHandle.send(null);
}
// ajax请求状态监听
function show() {
if (getHandle.readyState === 4) {
console.log(getHandle.responseText);
}
}
- PHP 代码
// aja get请求脚本
echo '成功返回数据';
- 效果
;
2.2 POST 方式
请求流程:
a. 创建请求对象:new XMLHttpRequest()
b. 监听请求回调:onreadystatechange
c. 初始化请求参数:open(请求类型,请求地址,是否异步)
d. 设置请求头:setRequestHeader()
e. 发送请求:send(data)
响应:
a. 服务器: 返回JSON
b. 前端:JSON.parse()
解析 JSON 字符串
注意:post 与 get 相比, 多了一步设置请求头。
表单数据格式
前端发送JSON
,后端如果 json 数据以表单数据类型发送,可用$_POST
接收,数据是常见表单名值对格式。- JS 代码
// 运用ajax post 表单名值对格式(application/x-www-form-urlencoded)方式请求数据
// 建立句柄
const handle = new XMLHttpRequest();
// console.log(handle);
// 监听状态 0,1,2,3,4
handle.addEventListener("readystatechange", show, false);
//设定请求方式
handle.open("POST", "test2.php", true);
//设置请求头
handle.setRequestHeader("content-type", "application/x-www-form-urlencoded");
// 请求数据(伪数据)
const user = {
name: "zhangshan",
age: 30,
};
//因为php无法识别js的数据格式,因此此处要把数据转为跨语言的json字符串格式
let data = JSON.stringify(user);
// console.log(data);
// 发送ajax post请求
handle.send(data);
function show(e) {
if (handle.readyState == 4) {
console.log(handle.responseText);
}
// console.log(readstate);
}
- PHP 代码
// ajax post请求脚本
$data = key($_POST);
echo $data;
- 效果
;
json 数据格式
如果 json 数组就是以 JSON 发送,php://input
流文件方式接收- JS 代码
// 向服务器传输json格式数据
// 建立句柄
const handle = new XMLHttpRequest();
// 监听事件 onreadystatechange 监听readystate属性状态 状态
handle.addEventListener("readystatechange", change, false);
//设置ajax 请求方式 post get
handle.open("POST", "test3.php", true);
//设置请求头
handle.setRequestHeader("content-type", "application/json;charset=utf-8");
//伪数据
const data = {
name: "zhangshan",
age: 30,
};
// 转为json 字符串
let jsonData = JSON.stringify(data);
// console.log(jsonData);
//请求
handle.send(jsonData);
function change(obj) {
if (handle.readyState === 4) {
console.log(handle.responseText);
}
}
- PHP 代码
//ajax 传递json格式字符串脚本
//接收前端传来的json格式的数据.因为数据格式不是表单数据,所以不能用$_POST接收
// $user = $_POST;
//用php://input;
$user = file_get_contents('php://input');
echo $user;
- 效果
;
FormData 封装表单数据数据
FormData 数据不需要设置请求头,因为在 FormData 对象中已经封装了请求头信息- HTML 代码
<form action="" onsubmit="return false">
<input type="text" name="username" value="李四" placeholder="用户名" />
<input type="password" name="psd" value="123456" placeholder="用户名" />
<button type="button">提交</button>
</form>
- JS 代码
// 点击发送ajax
let form = document.querySelector("form");
// 获取button,表单数据
let btn = document.querySelector("button");
//button添加点击事件
btn.addEventListener("click", sumbumit, false);
// ajax请求
const handle = new XMLHttpRequest();
// 监听readystate 状态,用onreadystatechange方法监听
handle.addEventListener("readystatechange", show, false);
//设置ajax 请求方式 post get
handle.open("POST", "test4.php", true);
//提交回调:FormData封装表单数据提交
function sumbumit(ev) {
// 发送数据
handle.send(new FormData(form));
}
// ajax请求状态监听
function show() {
if (handle.readyState === 4) {
console.log(handle.responseText);
}
}
- PHP 代码
// ajax FormData 返回
print_r($_POST);
- 效果
;
二,jsonp 跨域的问题
浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源.
1,原因
同源策略
1995 年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页”同源”。
所谓”同源”指的是”三个相同”。
- 协议相同
- 域名相同
- 端口相同
举例:
# 协议不同
https://www.php.cn:443 /course/812.html
http:// www.php.cn:443 /course/812.html
# 端口不同
http://www.php.cn:80 /wenda/165068.html
http://www.php.cn:8080 /wenda/165068.html
# 域名不同
http://www.php.net:80 /wenda/165068.html
http://www.php.cn:80 /wenda/165068.html
2,跨域原理
script
标签允许跨域请求脚本:<script src="...."></script>
- 动态生成
<script>
元素,并将需要跨域访问的 URL,赋值给 script 元素的 src 属性 - 在跨域访问的服务器脚本中(如 php),将数据转为 json 格式,直接返回给前端处理就可以了
注意:在访问的 URL 中一定要带上 callback 回调函数,回调函数是在当前请求的 js 脚本中申明,并在 php 中调用返回数据。
3,实现
- HTML 代码
<button class="btn">跨域请求</button>
- JS 代码
// 由于浏览器同源策略,我们没法拿到其他网站的数据,为了规避它,我们运用jsonp跨域
// 在脚本中生成 script 标签
let btn = document.querySelector("button.btn");
btn.addEventListener("click", creatScript, false);
function creatScript(ev) {
// script请求地址
let url = "http://www.test.com/test1.php?id=1&callback=show";
// 生成script标签对象
let script = document.createElement("script");
script.src = url;
document.head.appendChild(script);
}
function show(data) {
console.log(data);
}
- PHP 代码
$data = [
['id'=>1,'name'=>'zhangshan','age' => 20],
['id'=>2,'name'=>'lisi','age' => 30],
['id'=>1,'name'=>'wanmazi','age' => 40],
];
$id = $_GET['id'];
//echo $id;die;
$callback = $_GET['callback'];
$ret;
foreach($data as $value) {
if($value['id'] == $id) {
$ret = $value;
break;
}
}
$ret = json_encode($ret);
echo "{$callback}({$ret})";
- 效果
;
三,总结
学习了 js 一段时间,感觉有点难度!主要是属性和对象太多了,还是要多敲代码,才能熟能生巧!