Ajax异步通信与JSON数据类型
什么是Ajax
Ajax 的全称是 Asynchronous JavaScript And XML (异步Javascript和XML)。
它不是一项新的技术,而是由多种技术组合而成。
2005年2月18日,Adaptive Path公司的Jess James Garrett发表了一篇名为:
Ajax:A NewApproach to Web Applications(Ajax技术:开发web应用的新思路)的文章。
说白了Ajax技术说的是把Javascript、Css、Dom和(X)HTML结合起来的一种新用法。
这种结合并不是新概念,事实上DHTML技术早就把这几样技术结合在一起了。
Ajax的独到之处在于它在服务器端使用了异步(Asynchronous)处理技术。
Ajax包含了以下几种技术
基于web标准(standards-based presentation)XHTML+CSS的表示;
使用 DOM(Document Object Model)进行动态显示及交互;
使用 XML 和 XSLT 进行数据交换及相关操作;
使用 XMLHttpRequest 进行异步数据查询、检索;
使用 JavaScript 将所有的东西绑定在一起。
类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。
Ajax与传统Web程序的区别
图1.传统Web模式的工作流程
图2.Ajax程序的工作流程
jQuery.ajax
通过 HTTP 请求加载远程数据。
jQuery 底层 AJAX 实现。简单易用的高层实现见 $.get, $.getJSON, $.post 等。
$.ajax() 返回其创建的 XMLHttpRequest对象。
要加载jq库文件
jQuery.ajax(url,[settings]):通过 HTTP 请求加载远程数据。
参数 | 说明 |
---|---|
url | 一个用来包含发送请求的URL字符串。 |
settings | AJAX 请求设置。所有选项都是可选的。 |
// 加载jq库
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
// ajax请求
<script>
$.ajax({
type: 'get',//请求的方式
url: "jq_ajax.php",//请求的地址
data: {// 请求参数
username: username,
pwd: pwd
},
datetype: 'json',//预期服务器返回的数据类型
success: function (z) {// 成功回调的函数
console.log(z);
}
error:function(error){// 错误回调的函数
console.log(error);
}
})
</script>
同源策略
同源策略,它是由Netscape提出的一个著名的安全策略。
现在所有支持JavaScript 的浏览器都会使用这个策略。
所谓同源是指,域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开来
百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,
即检查是否同源,只有和百度同源的脚本才会被执行。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
jsonp跨域 && CORS跨域
首先抛出浏览器同源策略这个概念,为了保证用户访问的安全,现代浏览器使用了同源策略,即不允许访问非同源的页面
在ajax中,不允许请求非同源的URL就可以了,比如www.a.com下的一个页面,
其中的ajax请求是不允许访问www.b.com/c.php这样一个页面的。
JSONP就是用来解决跨域请求问题的
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,
利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码
在src中进行了调用,这样实现了跨域。
跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,
允许网页从不同的域访问其资源。
CORS就是为了让AJAX可以实现可控的跨域访问而生的.
CORS与JSONP相比:
JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
JSONP主要被老的浏览器支持,但它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。
本质是HTML5 xhr level2原生ajax请求!
CORS只需要在后台中加上响应头来允许域请求!
在被请求的Response header中加入以下设置,就可以实现跨域访问了!
//指定允许其他域名访问
'Access-Control-Allow-Origin:*'//或指定域
//响应类型
'Access-Control-Allow-Methods:GET,POST'
//响应头设置
'Access-Control-Allow-Headers:x-requested-with,content-type'
demo.html
<script type="text/javascript">
$.ajax({
type: "get",
async: false,
url: "http://www.demo.com/demo.php",
dataType: "jsonp",
jsonp: "callback", //请求php的参数名
jsonpCallback: "jsonhandle",//要执行的回调函数
});
function jsonhandle(data)
{
console.log(data);
}
</script>
demo.php
<?php
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:POST');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, x-file-name");
$data = array(
'age' => 20,
'name' => '张三',
);
$callback = $_GET['callback'];
echo $callback."(".json_encode($data).")";
exit;
?>
JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
易于人阅读和编写。同时也易于机器解析和生成。
它基于 JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯
(包括C, C++, C#, Java, JavaScript, Perl, Python等)
JSON有两种结构:对象结构,数组结构
对象结构是使用大括号“{}”括起来的,大括号内是由0个或多个用英文逗号分隔的“关键字:值”对(key:value)构成的。
var jsonObj =
{
"键名1":"值1",
"键名2":"值2",
……
"键名n":"值n"
}
JSON数组结构是用中括号“[]”括起来,中括号内部由0个或多个以英文逗号“,”分隔的值列表组成。
var arr =
[
{
"键名1":"值1",
"键名2":"值2"
},
{
"键名1":"值3",
"键名2":"值4"
}
]
用于Ajax或者数据交互的数据格式的统一,但是还有另一种用于数据交互时的数据格式统一的可扩展标记语言,简称XML
它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或服务器的结构化数据。
JSON库中有一个全局JSON对象, 有2个方法:parse() 和 stringify()
parse() 用于从一个字符串中解析出json 对象
JSON.parse(text [, reviver])
参数 | 说明 |
---|---|
text | text 必需。 有效的 JSON 文本 |
reviver | reviver 选项。 筛选和转换的结果的函数 |
//切记 js语句中 字符串包含json格式的数据外层最好用单引号
var jsontext ='{"firstname":"Jesper","surname":"Aaberg","phone":["555- 0100","555-0120"]}';
var contact = JSON.parse(jsontext);
var fullname = contact.surname + "," + contact.firstname;
stringify 方法用于从一个对象解析出字符串
JSON.stringify(value [, replacer] [, space])
参数 | 说明 |
---|---|
value | 必需,JavaScript 值,该值通常对象或数组,将序列化 |
replacer | 筛选和转换的结果的函数或数组 |
space | 添加缩进,空白和换行符到的返回值JSON文本使代码更容易阅读 |
var arr=['apple','banana',{test:'123'}];
var z= JSON.stringify(arr);
//["apple","banana",{"test":"123"}]
console.log(z);
PHP中接收和传递JSON
json_decode — 对 JSON 格式的字符串进行编码
json_encode — 对变量进行 JSON 编码
json_decode
mixed json_decode ( string $json [, bool $assoc ] )
参数 | 说明 |
---|---|
json | 待解码的 json string格式的字符串 |
assoc | 当该参数为 TRUE 时,将返回 array 非 object |
使用json_decode的一些注意事项
使用UTF-8编码
不能在最后元素有逗号
不能使用单引号
不能有\r,\t,如果有请替换
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
var_dump(json_decode($json, true));
json_encode
string json_encode ( mixed $value )
参数 | 说明 |
---|---|
value | 待编码的value |
$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
echo json_encode($arr);
// {"a":1,"b":2,"c":3,"d":4,"e":5}
Promise基本⽤法
promise是一个对异步操作进行封装并返回其结果的构造函数,⾃⼰身上有all、reject、resolve等⽅法,
原型上有then、catch 等⽅法; new出来的Promise对象就有then、catch⽅法;
Promise传⼊两个参数:resolve,reject,
分别表示异步操作执⾏成功后的回调函数和异步操作执⾏失败后的回调函数;
1.初始化,状态:pending
2.当调用resolve(成功),状态:pengding=>fulfilled
3.当调用reject(失败),状态:pending=>rejected
then函数里的参数是两个异步回调函数,是异步的哈,第一个参数函数用于接收resolve返回来的数据,
第二个参数函数用于接收eject返回的数据。
function testReject()
{
var p = new Promise(function (resolve, reject) {
//做⼀些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10);
//⽣成1-10的随机数
if(num <= 5){
resolve(num);
}else{
reject('数字超出了范围');
}
}, 2000);
});
return p;
}
testReject().then(
function(data) {
console.log('resolved状态');
console.log(data);
},
function(reason, data) {
console.log('rejected状态');
console.log(reason);
}
);
Promise.all()方法
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
// (3) [3, 42, 'foo']
});
async/await
await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。
async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,
等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。
async
async function demo()
{
var p1 = new Promise(function(resolve,reject){
resolve('成功')
})
//同步执行
//var res = await p1;
//console.log(res)
//异步执行
p1.then(success => console.log(success))
console.log('看谁先执行')
}
demo()
await
async function demo()
{
var p1 = new Promise(function(resolve,reject){
resolve('成功')
})
//同步执行
var res = await p1;
console.log(res)
//异步执行
// p1.then(success => console.log(success))
console.log('看谁先执行')
}
demo()