Ajax、jsonp
1、ajax简介
AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用AJAX)如果需要更新内容,必须重载整个网页页面。
2、进程与线程
线程:
一个线程是一个程序内部的一个顺序控制流。
即:一个或多个线程组成了一个进程。
进程:
可以简单的理解为一个正在运行的程序。
进程与进程间是互相独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响。
线程的本质就是一小部分独立的代码,当进程欲行时,它会衍生出一个线程,即:主线程。主线程实际上就是程序中的main()函数,可以决定衍生出多个线程(单线程应用程序);或者也可以在内存的允许下,衍生出多个线程。
3、同源策略
同源策略:
简单的说就是要求动态内容,只能阅读与之同源的那些HTTP应答和cookies,而不能阅读来自不同源的内容。
同源的三大要素:http://22.19.89.989:8080/scripts
1、同协议:同http或同https
2、同域名/同IP:www.baidu.com/22.19.89.989
3、同端口:8080 http默认端口80
为什么要端口? 因为服务器上的服务可能很多,一个请求过来,怎么判断是请求数据的服务呢?端口就是为了区分这些请求的。
端口的作用就是帮助服务器区分请求的类型的。
为什么要有同源策略?
为了保证数据安全,防止恶意攻击。
非同源页面数据怎么访问呢?
1、跨域访问cross(服务器端)
2、jsonp
4、XMLHttpRequest
形式1)
//把参数以对象的形式传递
function ajax(obj){
//1、创建一个XMLHttpRequest对象
var xhr = tool.createXHR();
obj.url = obj.url + "?rand=" + Math.random();
//加个随机参数,在不影响请求的情况下,让浏览器感觉每次发送的都是一个新的地址,以防止相同请求后面的覆盖前面的请求效果
//2、初始化
//判断请求方式
if(obj.async == true){
xhr.open(obj.method,obj.url);
}else{
xhr.open(obj.method,obj.url,false);
}
//3、发送请求
//判断方式类型
// xhr.setRequestHeader("Content-type","application/json");
// xhr.setRequestHeader("Content-type","application/www-form-urlencoded");
if (obj.sendType == "application/json") {
xhr.setRequestHeader("Content-type","application/json")
xhr.send(JSON.stringify(obj.data));
} else if (obj.sendType == "application/www-form-urlencoded") {
xhr.setRequestHeader("Content-type","application/www-form-urlencoded");
xhr.send(handleData(obj.data));
} else{
throw new Error("其它的数据格式发送未支持!");
};
//4、处理接收的响应
xhr.onreadystatechange = function(){
if (xhr.status == 200 || xhr.status == 304) {
if (xhr.readyState == 4) {
callback();//回调函数
}
}
}
function callback(){
obj.success(xhr.responseText);
}
}
function handleData(data){
var ar = [];
for(var p in data){
ar.push(p+"="+data[p]);//把对象的属性和对应的值存进数组
}
return ar.join("&");//将数组用&连接成字符串
}
形式2)
//用对象字面量封装Ajax
var Ajax = {
/*
* 参数解释:
* method : 请求方式
* url : 请求地址(要解析的json文件路径)
* data : 参数
* successCallBackFn : 成功回调函数
* failCallBackFn :失败回调函数
*
*/
ajaxFn : function(method, url, data, successCallBackFn, failCallBackFn){
//1、创建异步请求对象
var xhr;
if(window.XMLHttpRequest){
//IE6+ 和其它主流浏览器
xhr = new XMLHttpRequest();
}else if (window.ActiveXObject) {
//IE6-
var versionArr = ["Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for (var tempVersion of versionArr) {
xhr = new ActiveXObject(tempVersion);
if (xhr) {//如果已经创建,则跳出
break;
}
}
}else{
//浏览器不支持,抛出错误
throw new Error("您的浏览器不支持!!!");
}
//2、3打开服务器的链接和发送请求
if(method == "GET" || method == "get"){
//get请求有可能会有缓存
//解决方法是在地址后面添加一个随机参数,就是为了每次调用时改变地址
xhr.open(method,url + "?" + data + "&randomNum=" + Math.random() );
xhr.send(null);
}else if(method == "POST" || method == "post"){
//注意:如果是POST请求,那么在调用send方法之前,要设置请求头。
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.open(method, url);
xhr.send(data);
}else{
throw new Error("请求方式不正确!");
}
//4、接收服务器的响应
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 ) {
if(xhr.status == 200){
//响应成功
successCallBackFn(JSON.parse(xhr.responseText));
}else{
//响应失败
failCallBackFn("请求失败!");
}
}
}
}
}
5、json
json:
JSON是JS的一个子集,其格式和JS中的对象字面量语法一模一样,只是JSON是字符串而已,我们需要通过一下方式进行转换。
序列化:
把JS对象字面量转换成JSON字符串的操作叫做序列化
转换方法:JSON.stringify(JS对象);
反序列化:
把JSON字符串转换成JS对象字面量的操作叫做反序列化
转换方法:JSON.parse(JSON字符串);
6、jsonp
/*
封装jsonp函数
参数:
url:请求地址
parameter:参数(对象类型,多个属性-值,表示多个参数)
callback:回调函数
*/
function jsonp(url, parameter, callback){
//1、动态创建script标签
var script = document.createElement("script");
//2、拼接callback
//2.1生成回调函数名字
var callbackName = "cb" + new Date().getTime();
//2.2将回调函数绑定在window的callbackName(注意:callbackName这是变量)属性上
window[callbackName] = callback;
//2.3拼接callback到url上
url += "?callback=" + callbackName;
//http://10.xx.xx.xx:8080/getUser?callback=cb1234562
//3、拼接普通参数
//先判断参数是否存在
if (parameter) {
//遍历参数对象进行拼接
for(var prop in parameter){
url += ("&" + prop + "=" + parameter[prop]);
}
}
//4、设置script标签的src属性
script.src = url;
//5、加入到body中
document.body.appendChild(script);
//6、请求完之后清空,删除标签,防止下次地址叠加
//验证是否加载完毕
script.onload = function(){
document.body.removeChild(this);
//this 指向当前加载完毕之后的script
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>使用jsonp封装好的函数</title>
<script type="text/javascript" src="jsonp.js"></script>
</head>
<body>
<input type="button" value="无参数请求" />
<input type="button" value="有参数请求" />
<script type="text/javascript">
//无参
document.getElementsByTagName("input")[0].onclick = function(){
jsonp("http://10.0.153.177:4100/getXiaoXue",null,function(data){
console.log(data);
});
};
//带参
document.getElementsByTagName("input")[1].onclick = function(){
jsonp("http://10.0.153.177:4100/login",{
//对象字面量
username:"admin",
pwd:"123456"
},function(data){
console.log(data);
});
};
</script>
</body>
</html>
7、浏览器和服务器交互机制
浏览器和服务器之间进行通信,是通过Socket套接字进行的。
众所周知,现在我们所用的协议都是Http协议,而Http协议是无状态的协议。无状态协议是怎么样的一种协议呢。用通俗一点的话说,用户通过浏览器向服务器发出请求,发出请求之后,浏览器是不会记住当前用户是谁,是谁希望浏览器向服务器发送服务请求的(那么,有些朋友会说,为什么我用浏览器查看下一页 后一页会有显示呢,这就是很多朋友没弄清楚的地方,这是浏览器替用户缓存了页面,而不是Http协议缓存了页面,注意 注意!),浏览器在将服务器返回的数据呈现给用户后,Http协议会自动断开,不会一直替用户工作,因为服务器的资源是很宝贵的,监听此次请求的套接字会立即释放,然后去监听下一个请求!
浏览器获得了服务器的响应后,一次请求-发送请求-处理请求-返回处理结果这样一个过程也就结束了,Http协议就完成了一次工作,然后Http协议就不会关心用户在页面上所做的任何事情,直到用户再次请求!这就是一次浏览器和服务器最简单的交互!
输入完网址按下回车,到看到网页这个过程中发生了什么
a. 域名解析
b. 发起TCP的3次握手
c. 建立TCP连接后发起http请求
d. 服务器端响应http请求,浏览器得到html代码
e. 浏览器解析html代码,并请求html代码中的资源
f. 浏览器对页面进行渲染呈现给用户
8、get与post请求
1.get是从服务器上获取数据,post是向服务器传送数据。
2.get安全性非常低,post安全性较高。
3.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
4.get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
5.对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。