组团学

ES5进阶-AJAX

阅读 (526)

一、通信原理

  • URL

    统一资源定位符,是互联网上资源的地址

url2.png

  • 协议

    该URL的协议部分为"http:",这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,HTTPS,FTP等等,本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符

  • 域名

    该URL的域名部分为"www.sunck.wang"。一个URL中,也可以使用IP地址作为域名使用

  • 端口

    跟在域名后面的是端口,域名和端口之间使用":"作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口(HTTP为80,HTTPS为443)

  • 虚拟目录

    从域名后的第一个“/”开始到最后一个"/“为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分,本例中的虚拟目录是”/news/"

  • 文件名

    从域名后的最后一个"/“开始到”?“为止,是文件名部分,如果没有”?",则是从域名后的最后一个"/“开始到”#“为止,是文件部分,如果没有”?“和”#",那么从域名后的最后一个"/“开始到结束,都是文件名部分。本例中的文件名是"index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名

  • 参数

    从"?“开始到”#“为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“ID=34256&page=1”。参数可以允许有多个参数,参数与参数之间用”&"作为分隔符

  • 从"#"开始到最后,都是锚部分,本例中的锚部分是“name”,锚部分也不是一个URL必须的部分

  • 同源策略

    要求动态内容(如JavaScript)只能阅读与之同源的那些HTTP应答和cookies,而不能阅读来自非同源的内容

image20200305091731170.png

问答:

截屏2020030509_18_23.png

  • 我们是如何通过浏览器访问页面的?(了解内容B/S模式)

    思考:当我们打开浏览器,在浏览器的地址栏中输入URL地址"http://www.sunck.wang:8080/WebDemo1/1.html"去访问服务器上的1.html这个web资源的过程中,浏览器和服务器都做了神马操作呢,我们是怎么在浏览器里面看到1.html这个web资源里面的内容的呢?

    浏览器和服务器做了以下几个操作:

    • 浏览器根据主机名"www.sunck.wang"去操作系统的Hosts文件中查找主机名对应的IP地址
    • 浏览器如果在操作系统的Hosts文件中没有找到对应的IP地址,就去互联网上的DNS服务器上查找"www.sunck.wang"这台主机对应的IP地址
    • 浏览器查找到"www.sunck.wang"这台主机对应的IP地址后,就使用IP地址连接到Web服务器
    • 浏览器连接到web服务器后,就使用http协议向服务器发送请求,发送请求的过程中,浏览器会向Web服务器以Stream(流)的形式传输数据,告诉Web服务器要访问服务器里面的哪个Web应用下的Web资源
    • 浏览器做完上面4步工作后,就开始等待,等待Web服务器把自己想要访问的1.html这个Web资源传输给它
    • 服务器接收到浏览器传输的数据后,开始解析接收到的数据,服务器解析"GET /WebDemo1/1.html "里面的内容时知道客户端浏览器要访问的是WebDemo1应用里面的1.html这个Web资源,然后服务器就去读取1.html这个Web资源里面的内容,将读到的内容再以Stream(流)的形式传输给浏览器
    • 浏览器拿到服务器传输给它的数据之后,就可以把数据展现给用户看了
  • 早期页面交互

image20200305092416672.png

  • 现在页面交互

image20200305092439277.png

  • 同步交互

    提交请求–>等待服务器处理–>服务器返回数据,在此期间页面不能进行任何操作(B/S模式)

  • 异步交互

    请求通过事件触发–>服务器处理(然后可以做其他的事情)–>服务器进行响应(ajax)

  • 同步与异步举例

    异步:你传输吧,我去忙其他事情了,传完之后告诉我
    同步:你传输,我就静静的看你传完之后我在去做其他的事情

  • 屌丝与女神

image20200305092710430.png

  • ajax通信原理

image20200305092731788.png

二、Apache服务器安装与使用

  • 介绍

    • Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,是目前世界上使用最广泛的一种web server,它以跨平台,高效和稳定而闻名,可以运行在几乎所有广泛使用的计算机平台上。Apache的特点是简单、速度快、性能稳定,并可做代理服务器来使用。
    • Apache是用C语言开发的基于模块化设计的web应用,总体上看起来代码的可读性高于php代码,它的核心代码并不多,大多数的功能都被分割到各种模块中,各个模块在系统启动时按需载入。
    • 支持SSL技术,支持多个虚拟主机。Apache是以进程的Prefork模式(还有基于线程的Worker模式)为基础的结构,进程要比线程消耗更多的系统开支,不太适合于多处理器环境,因此,在一个Apache Web站点扩容时,通常是增加服务器或扩充群集节点而不是增加处理器
  • 安装

    • 官网下载安装包

13890167.png

  • 将安装包拷贝到某个盘下并解压

23890596.png

  • 进入Apache24下的conf目录,并打开httpd.conf文件(建议使用sublim打开)

3.png

  • 修改相应配置后保存关闭配置文件

4.png

5.png

  • 以管理云身份打开黑屏终端

553891365.png

  • 进入Apache24下的bin目录

6.png

  • 执行安装命令[httpd.ext -k install -n “Apache24”]

7.png

  • 成功提示

8.png

  • 解决虚拟机443端口问题(不解决Apache服务无法启动)

    编辑–>首选项–>共享虚拟机

13.png

  • 启动Apache服务

103892262.png

11.png

12.png

  • 如果安装出现问题,建议卸载后重新操作

    卸载命令:httpd.ext -k uninstall -n “Apache24”

  • 使用

    • 创建简单界面,放入Apache24下的htdocs目录下

14.png

  • 浏览器访问

15.png

三、ajax实现通信

截屏2020031110.59.02.png

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>home</title> </head> <body> <button id="btn">发起ajax请求</button> <script type="text/javascript"> var jsBtn = document.getElementById("btn"); jsBtn.addEventListener("click", function(){ //0、创建xhr对象 var xhr = new XMLHttpRequest(); // console.log(xhr); xhr.onreadystatechange = myCallBack; //1、初始化请求 /** * parameter1:设置请求类型(get或者post) * parameter2:设置请求url * parameter3:设置是否异步,true异步,flase同步。默认使用异步 */ xhr.open("get", "http://192.168.1.13:8090/test.txt", true); //2、发送请求 /** * 初始化时使用get时不用传参 * 初始化时使用post传参 */ xhr.send(); //3、接收返回数据 function myCallBack() { //3.1判断http响应状态 //200与304状态吗说明请求通信正常 if (xhr.status == 200 || xhr.status == 304) { if (xhr.readyState == 4) { //4、处理数据 console.log(xhr.responseText); } } } console.log("-----------") }, false); </script> </body> </html>
  • XMLHttpRequest对象核心属性

截屏2020030509.57.29.png

  • on……

    触发某种事件后对应的事件处理程序(事件监听器)

    onreadystatechange:服务器响应客户端后执行

  • readyState

    请求状态

    说明
    0 创建xhr对象
    1 初始化请求
    2 发送请求
    3 接收到响应
    4 完成接收数据
  • response

    服务器响应的数据

  • responseText

    服务器响应的数据(字符串类型)

  • responseType

    服务器响应数据的类型

  • responseURL

    响应请求的网址

  • responseXML

    当返回的数据是(text/xml或application/xml)等类型响应也会存在该字段中

  • status

    http响应状态

  • statusText

    http状态说明

  • timeout

    设置超时时间

  • http响应状态

截屏2020030510.12.24.png
点击百度百科查看具体说明

四、请求Json文件

截屏2020031110.08.48.png

  • Json

    概念:一种保存数据的格式,可以保存本地的json文件,也可以将json串进行传输,通常将json称为轻量级的传输方式

    json文件的基本构成:

    结构 说明
    {} 代表对象
    [] 代表数组
    : 代表属性对
    , 分隔两个部分

截屏2020030510.27.40.png

typ说明:

类型 说明
Array 数组
Object 对象
String 字符串
Number 数字
Boolean 布尔
Null

截屏2020030510.27.04.png

  • 请求

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>index</title> </head> <body> <button id="btn">发起ajax请求</button> <script type="text/javascript"> var jsBtn = document.getElementById("btn"); jsBtn.addEventListener("click", function(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = myCallBack; xhr.open("get", "http://192.168.1.13:8090/caidan.json", true); xhr.send(); function myCallBack() { if (xhr.status == 200 || xhr.status == 304) { if (xhr.readyState == 4) { console.log(xhr.responseText); console.log(typeof xhr.responseText); // 将json字符串转成字面量对象 var jsObj = JSON.parse(xhr.responseText); console.log(jsObj); console.log(typeof jsObj); // 将字面量对象转成json字符串 var jsStr = JSON.stringify(jsObj); console.log(jsStr); console.log(typeof jsStr); } } } console.log("-----------") }, false); </script> </body> </html>

五、常见的HTTP请求方式

方法 说明
GET 向特定的路径资源发出请求,数据暴露在url中
POST 向指定路径资源提交数据进行处理请求(一般用于上传表单或者文件),数据包含在请求体中
DELETE 请求服务器删除指定的数据
PUT 从客户端向服务器传送的数据取代指定的文档的内容
PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新
HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
OPTIONS 允许客户端查看服务器的性能
TRACE 回显服务器收到的请求,主要用于测试或诊断
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器

六、GET与POST的区别

  • 传参方式

    GET的形式把参数拼接在请求路径后面传给服务器

    POST把参数进行打包,单独去传输

  • 优缺点

    GET:速度快,数据小(当不对服务器数据进行更改时建议使用get方式)

    POST:速度慢,数据大,安全(当对服务器数据进行更改时建议使用post方式)

    说明:从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文,要想安全传输,就只有加密,也就是 HTTPS

  • GET示例

    var xhr = new XMLHttpRequest(); xhr.onreadystatechange = myCallBack; xhr.open("get", "http://192.168.1.13:8090/caidan.json?x=1&y=2", true); xhr.send(); function myCallBack() { if (xhr.status == 200 || xhr.status == 304) { if (xhr.readyState == 4) { console.log(xhr.responseText); console.log(typeof xhr.responseText); } } }
  • POST示例

    var xhr = new XMLHttpRequest(); xhr.onreadystatechange = myCallBack; xhr.open("post", "http://192.168.1.13:8090/caidan.json", true); xhr.send("{x:1, y:2}"); function myCallBack() { if (xhr.status == 200 || xhr.status == 304) { if (xhr.readyState == 4) { console.log(xhr.responseText); console.log(typeof xhr.responseText); } } }

    注意:post 需要你有服务器去处理post请求,get 的话Hbulider里面有一个内置的服务器可以处理,但是post不行

七、xhr兼容性问题

原因:IE低版本浏览器不支持XMLHttpRequest

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <script type="text/javascript"> var xhr = null; if (typeof XMLHttpRequest != "undefined") { xhr = new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined") { // 低版本的IE浏览器 var versionArr = ["MSXML.XMLHttp.6.0","MSXML.XMLHttp.3.0","MSXML.XMLHttp"]; for (var i = 0; i < versionArr.length; i++){ try{ xhr = new ActiveXObject(versionArr[i]); break; } catch(err){ console.log(err); } } if (i == 3){ alert("您的浏览器版本太低,请升级版本!"); } } else { alert("您的浏览器版本太低,请升级版本!"); } xhr.onreadystatechange = myCallBack; xhr.open("get", "tset.txt", true); xhr.send(); function myCallBack(){ if (xhr.status == 200 || xhr.status == 304){ if (xhr.readyState == 4){ console.log(xhr.responseText); } } } </script> </body> </html>

八、封装xhr

xhr.js

function MyAjax(method, url, isAsyn, sendParam, callBack){ this.method = method; this.url = url; this.isAsyn = isAsyn; this.sendParam = sendParam; this.callBack = callBack; this.xhr = null; this.createXHR = function(){ if (typeof XMLHttpRequest != "undefined") { return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined") { var versionArr = ["MSXML.XMLHttp.6.0","MSXML.XMLHttp.3.0","MSXML.XMLHttp"]; for (var i = 0; i < versionArr.length; i++){ try{ return new ActiveXObject(versionArr[i]); break; } catch(err){ console.log(err); } } if (i == 3){ alert("您的浏览器版本太低,请升级版本!"); } } else { alert("您的浏览器版本太低,请升级版本!"); } } this.send = function(){ this.xhr = this.xhr || this.createXHR(); var url = this.url; if (this.method.toUpperCase() == "GET"){ url += "?"; var temp = ""; for (var i in this.sendParam){ temp += (i + "=" + this.sendParam[i] + "&"); } url += temp.substr(0, temp.length - 1); } this.xhr.open(this.method, url, this.isAsyn); if (this.method.toUpperCase() == "GET"){ this.xhr.send(); } else { this.xhr.send(JSON.stringify(this.sendParam)); } this.xhr.onreadystatechange = this.callBack; } }

index.html

function myCallBack() { if (xhr.xhr.status == 200 || xhr.xhr.status == 304) { if (xhr.xhr.readyState == 4) { console.log(xhr.xhr.responseText); } } } var xhr = new MyAjax("get", "http://127.0.0.1:8848/code/caidanJson.json", true, {x:1, y:2}, myCallBack); xhr.send();

九、跨域访问

  • 何为跨域?

    同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略, 浏览器很容易受到 XSS、CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同, 即便两个不同的域名指向同一个 ip 地址,也非同源 ,非同源无法访问。访问非同源的链接即为跨域访问

234.png

  • 请求跨域了,那么请求到底发出去没有?

    跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结 果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内 容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟 是发出去了

  • 特别说明

    • 如果是协议和端口造成的跨域问题“前台”是无能为力的
    • 在跨域问题上,仅仅是通过“URL 的首部”来识别而不会根据域名对应的 IP 地址 是否相同来判断。“URL 的首部”可以理解为“协议, 域名和端口必须匹配”
  • 方式

    • jsonp
    • cors
    • postMessage
    • websocket
    • Node 中间件代理
    • nginx 反向代理
    • window.name + iframe
    • location.hash + iframe
    • document.domain + iframe
  • jsonp实现跨域

    原理:利用 script 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP 请求一定需要对方的服务器做支持才可以

    与ajax对比:JSONP 和 AJAX 相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但 AJAX 属于同源策略,JSONP 属于非同源策略(跨域请求)

    优缺点:JSONP 优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持 get 方法具有局限性,不安全可能会遭受 XSS 攻击

    实现流程:

    • 声明一个回调函数,其函数名(如 show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的 data)
    • 创建一个script标签,把那个跨域的 API 数据接口地址,赋值给 script 的 src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)
    • 服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是 show,它准备好的数据是show('我不爱你')
    • 最后服务器把准备的数据通过 HTTP 协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作

    实现代码:

    function show(data){ console.log("-----------"); console.log(data); } //动态创建一个script标签 var JSONP = document.createElement("script"); JSONP.type = "text/javascript"; //script的src属性可以跨域 JSONP.src = "http://crossdomain.com/jsonServerResponse?callback=show"; document.getElementsByTagName("head")[0].appendChild(JSONP);
  • 总结

    • CORS 支持所有类型的 HTTP 请求,是跨域 HTTP 请求的根本解决方案
    • JSONP 只支持 GET 请求,JSONP 的优势在于支持老式浏览器,以及可以向不支持 CORS 的网站请求数据。
    • 不管是 Node 中间件代理还是 nginx 反向代理,主要是通过同源策略对服务器不加限制。
    • 日常工作中,用得比较多的跨域方案是 cors 和 nginx 反向代理
需要 登录 才可以提问哦