前面咱们已经学习了js
基础知识和一些简单的特效,基本上已经可以写出一个带有特效的静态页面了,为何还要称之为静态页面呢?由于网页里的数据都是写死的,真正的工做中,咱们是要经过Ajax
技术,去后台获取数据的。因此在本篇文章,我会向你们介绍下什么是Ajax
技术,而且它的实现原理是什么。javascript
在学习
Ajax
以前,咱们首先须要知道什么是服务器。
一、什么是服务器?php
服务器的本质其实就是一台电脑,不过它不像通常的电脑同样拥有鼠标键、键盘、显示器等输入设备,它直接就是一个主机,里面只有主板、硬盘、
cpu
、内存而且性能比通常计算机的性能更高,稳定性更强。
PC
,服务器性能更好、安全性更高、稳定性更强。IDC
(对气候、能源、消防、建筑、安保等要求。服务器外观图:css
二、服务器提供什么服务html
根据需求的不一样,服务器的种类也有所不一样。
Web Server
)Mail Server
)Database Server
)FTP
服务器(FTP Server
)DNS Server
)三、服务器操做系统:前端
Windows Server
Linux
(Debian
,Ubuntu
,CentOS
,Fedora
)四、服务器的应用软件:java
Web
服务器(又称:http
服务器,主要提供文档的浏览功能,文本、图片、视频、音频)。mysql
IIS
(Windows
)Apache
Nginx
数据库服务器jquery
SQL Server
Oracle
MySQL
客户端: 经过网络向服务器请求服务的计算机就是客户端(手机、电脑);web
客户端软件: 在客户端计算机上运行的与服务器通信的软件就叫客户端软件;ajax
单机软件: 在客户端计算机上运行的不访问网络的软件叫作单机软件;
软件开发架构分为两种,分别是C/S
架构和B/S
架构。
一、C/S架构:
C/S
,是Client
:(客户端)和Server
(服务器)两个单词的简写,指的是客户端应用程序与服务器端应用程序通信的软件开发架构。
对于C/S
架构,最为常见的例子就是网络游戏,好比LOL
,若是不联网就没法使用。
优势:
缺点:
app
;二、B/S架构
B/S
,是Browser
:(浏览器)和Server
(服务器),两个单词的简写,指的是Web
浏览器与服务器端应用程序通信的软件开发架构。
如今全部的网站都是B/S
架构,好比知乎、网易云音乐、百度...,用户只需使用浏览器就能访问服务器;
优势:
缺点:
一、IP地址
IP
地址是网络上每一台设备通信时的身份标识(就像身份证、手机号)。
IP
地址长什么样子呢?
192.168.10.10
好比,百度的IP
地址就是:
119.75.213.61
特殊的IP
地址-表明本机:
127.0.0.1
如何查看当前IP
地址?
打开命令行工具,直接输入“ipconfig” ipconfig 命令
二、域名
域名简单的说,就是给IP
地址起一个容易记忆的名字(就比如人的名字同样)例如百度的域名:www.baidu.com
。
由于IP
地址记忆起来很是不方便,因此平常生活中用户经过域名来访问服务器更加方便。
特殊的域名:localhost
(表明本机)。
三、DNS 服务器
什么是DNS
?DNS
(Domain Name Server
),其实就是域名服务器。
输入网址后的访问流程(域名->DNS
->IP
地址)
查看域名与IP
地址的对应关系(ping
命令)
能够用Hosts
文件让本身的电脑变成一个属于本身的DNS
服务器。
四、网络端口(Port)
端口是指计算机与外界进行通信的数据出口(入口),每一个端口为不一样的应用传输不一样数据。
端口号: 每个端口都有一个端口号。范围是从0
到65535
。
端口号一般跟在IP
地址后面,用冒号分隔。例如:192.168.1.1:80
、www.jd.com:80
经常使用端口号: 80(HTTP)
、3306(MySQL)
、21(FTP)
。
查看本机被占用的端口状况(命令行输入:netstat
)
五、数据库
按照数据结构来组织、存储和管理数据的仓库,软件开发行业通常指的是数据库软件,常见的有Oracle
、MySQL
等。
特色:
DBA数据库管理员:
从事管理和维护数据库管理系统(DBMS
)的相关工做人员的统称。保证数据库的稳定性、安全性、完整性和高性能。
Web
服务器上的文件资源。HTML
网页、文本、图片、视频、音频、Web
服务器程序等。AMP
,A:Apache
,M:MySQL
,P:PHP
一、Apache:
世界排名第一的服务器软件,特色是:简单速度快,性能稳定。
二、MySQL:
体积小、速度快、使用成本低,并且仍是开源。
三、PHP:
超文本预处理器,直接将代码嵌入到HTML
文档中执行,简单易学,容易上手。
在本身的Windows
电脑上Web
服务器软件 - Wamp
。
WampServer
:Wamp
就是Windows
、Apache
、Mysql
、PHP
集成安装环境,即在window
下的apache
、
php
和mysql
的服务器软件。PHP
扩展、Apache
模块,开启/关闭鼠标点点就搞定,不再用亲自去修改
配置文件了,WAMP
它会去作。不再用处处询问php
的安装问题了,WAMP
一切都搞定了,这个软件
在windows
平台上使用的较多。
下载Wamp
:Wamp官网
安装Wamp
:安装的时候要区分版本(64
位,32
位),点击下一步下一步。
注意:安装目录的路径不能出现中文。
程序安装成功以后,任务栏里面的小图标是绿色的话,说明安装成功。
刚刚上面提到过,域名:localhost
和 IP
地址:127.0.0.1
均可以打开本地服务器:
当出现wamp
页面的时候说明软件安装成功。
web
服务器没有正常运行(测试web
服务器的端口号是否被占用)64
位版本、32
位版本要分清Web
服务器软件请先关闭一、基本功能使用:
修改语言 右击任务栏中的软件小图标==> language
==> chinese
Web服务器的启动、中止、运行: 左击小图标 (修改配置文件以后,必定要重启服务器);
功能介绍:Apache
其中两个配置文件后面可能须要修改,因此这里须要知道在哪找到它们。
看下它的配置文件-httpd.conf
,其中 #
表示的是注释的意思。
功能介绍:MySQL
看下它的配置文件-my.ini
,其中 ;
表示的是注释的意思:
功能介绍:PHP Apache
是一个web
服务器,它自己是不能解析PHP
语言的,因此这里也集成了一个PHP
解析器
看下它的配置文件-php.ini
,其中 ;
表示的是注释的意思:
一、为Web服务配置一个域名(仅限本机使用的域名)
找到C:\Windows\System32\drivers\etc\hosts
文件并修改
将本地的IP设置一个新的域名lxh.com
,重启Wamp
服务器,在地址栏里输入lxh.com
就会跳转到服务器页面:
二、自定义Web服务器的根目录
咱们能够看到,当咱们输入本地域名或者
IP
的时候,都会弹出来服务器的界面,假如我想要打开一个文件的时候怎么办呢?这时候咱们就须要配置服务器的根目录,只要是在根目录里面的文件,均可以经过服务器打开。
查找并打开安装目录D:\wamp64\bin\apache\apache2.4.23\conf\extra\httpd-vhosts.conf
文件:
打开修改配置文件,其中ServerName
指的是域名,咱们能够将第一步配好的本地域名地址写上去;DocumentRoot D:/lxhAjax
和<Directory "D:/lxhAjax/">
是自定义Web服务器的根目录为D:/lxhAjax
文件夹
三、为Web服务器配置虚拟主机(一台Web服务器当多台用)
在同一局域网下别人能够经过你的IP
访问你的Web
服务器文件夹。
httpd-vhosts.conf
文件中查找 Require local
Require local
改为 Require all granted
不过建议你们不要这样作,安全性不高,电脑里面的东西会被别人看到。
四、注意事项
php5.6
如下版本要设置php
默认编码,default_charset = UTF-8
,不然PHP
程序可能没法正确显示中文。httpd.conf
文件设置DocumentRoot
前,先检查是否已经关闭了虚拟主机,不然可能致使设置无效。默认状况下Wamp
服务器只能被本机访问,若是向被局域网的其余电脑访问须要修改配置
httpd-vhosts.conf
文件中查找 Require local
Require local
改为 Require all granted
ping
对方IP
#
”表示注释网络协议约定了网络计算机之间数据的传输的方式、数据的格式等。
常见的网络应用底层协议:
HTTP
、HTTPS
超文本传输协议FTP
文件传输协议SMTP
简单邮件传输协议HTTP协议:
HTTP
即超文本传输协议,网站是基于HTTP
协议的,好比咱们在开发网站中常用css
、js
、图片等等都是基于该协议传输的。
组成部分:
HTTP
协议是对请求(Request
)和响应(Response
)的报文内容进行了约束和规范。
请求: 客户机向服务器发送数据
响应: 服务器向客户机发送数据
发送并请求请求报文,接收响应报文,这种获取数据的方式咱们称之为HTTP
协议。
请求是由客户端发起,其规范格式为:请求行、请求头、请求主体。
一、请求行:
由请求方法、请求URL
和HTTP
协议及版本构成
GET /code/login.php?username=123&password=123 HTTP/1.1
POST /code/login.php HTTP/1.1
二、请求头:
这里设置的主要是一些信息,包含客户端,服务器。
User-Agent
:浏览器的具体类型,如:User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0
Accept
:浏览器支持哪些数据类型,如:Accept: text/html,application/xhtml+xml,application/xml;q=0.9;
Accept-Charset
:浏览器采用的是哪一种编码,如:Accept-Charset: ISO-8859-1
Accept-Encoding
:浏览器支持解码的数据压缩格式,如:Accept-Encoding: gzip, deflate
Accept-Language
:浏览器的语言环境,如:Accept-Language zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Host
:请求的主机名,容许多个域名同处一个IP
地址,即虚拟主机。Host:www.baidu.com
Connection
:表示是否须要持久链接。Keep-Alive/close
,HTTP1.1
默认是持久链接,它能够利用持久链接的优势,当页面包含多个元素时(例如Applet
,图片),显著地减小下载所须要的时间。要实现这一点,Servlet
须要在应答中发送一个Content-Length
头,最简单的实现方法是:先把内容写入ByteArrayOutputStream
,而后在正式写出内容以前计算它的大小。如:Connection: Keep-Alive
Content-Length
:表示请求消息正文的长度。对于POST请求来讲Content-Length必须出现。Content-Type
:WEB服务器告诉浏览器本身响应的对象的类型和字符集。例如:Content-Type: text/html; charset='gb2312'
Content-Encoding
:WEB
服务器代表本身使用了什么压缩方法(gzip,deflate
)压缩响应中的对象。例如:Content-Encoding:gzip
Content-Language
:WEB
服务器告诉浏览器本身响应的对象的语言。Cookie
:最经常使用的请求头,浏览器每次都会将cookie
发送到服务器上,容许服务器在客户端存储少许数据。Referer
:包含一个URL,用户从该URL
表明的页面出发访问当前请求的页面。服务器能知道你是从哪一个页面过来的。Referer: http://www.baidu.com/
三、请求体:
这里是提交给服务器的数据
须要注意的是,若是是往服务器提交数据,须要在请求头中设置Content-Type:application/x-www-form-urlencoded
(在ajax
中须要手动设置);
响应报文是服务器发回给客户端的。组成部分有状态行,响应头,响应主体。
一、状态行:
由协议版本号、状态码和状态信息构成
HTTP/1.1 200 OK
常见的状态码:
1XX
:信息状态码
100
Continue
继续,通常在发送post
请求时,已发送了http header
以后服务端将返回此信息,表示确认,以后发送具体参数信息2XX
:成功状态码
200
OK
正常返回信息201
Created
请求成功而且服务器建立了新的资源202
Accepted
服务器已接受请求,但还没有处理3XX
:重定向
301
Moved Permanently
请求的网页已永久移动到新位置。302
Found
临时性重定向。303
See Other
临时性重定向,且老是使用 GET 请求新的 URI。304
Not Modified
自从上次请求后,请求的网页未修改过。4XX
:客户端错误
400
Bad Request
服务器没法理解请求的格式,客户端不该当尝试再次使用相同的内容发起请求。401
Unauthorized
请求未受权。403
Forbidden
禁止访问。404
Not Found
找不到如何与 URI 相匹配的资源。5XX
: 服务器错误
500
Internal Server Error
最多见的服务器端错误。503
Service Unavailable
服务器端暂时没法处理请求(多是过载或维护)。二、响应头:
Date
:响应时间Server
:服务器信息Last-Modified
:资源最后修改时间 由服务器自动生成ETag
:资源修改后生成的惟一标识,由服务器自动生成Content-Length
:响应主体长度Content-Type
:响应资源的类型三、响应主体:
即服务端返回给客户端的内容;
Asynchronous Javascript And XML
(异步的Javascript
和XML
)。
思考:
咱们访问一个普通网站时,当浏览器加载完HTML
、CSS
、JS
之后,网站就固定了,若是网站内容发生改变,必须刷新网页后,才能看到更新内容。
Ajax概念:
在浏览器中,咱们可以不刷新页面,经过Ajax
的方式去获取一些新的内容。
Ajax
不是一门的新的语言,而是对现有技术的综合利用。HTTP
协议的基础上以异步的方式与服务器进行通讯。js
帮咱们预约义的一个异步对象XMLHttpRequest
来完成的AJAX
是一种用于建立快速动态网页的技术。经过在后台与服务器进行少许数据交换,AJAX
可使网页实现异步更新。这意味着能够在不从新加载整个网页的状况下,对网页的某部分进行更新。
优势:
缺点:
XMLHttpRequest
对象的支持度不足,存在兼容性;Ajax
干掉了back
按钮,即对浏览器后退机制的破坏;URL
直接访问;Ajax应用场景:
Ajax 包含如下五个部分:
Ajax
并不是一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。
CSS
和XHTML
来表示。DOM
模型来交互和动态显示。XML
与XSLT
XMLHttpRequest
来和服务器进行异步通讯。javascript
来绑定和调用。传统Web应用程序与Ajax Web应用程序对比:
主要的差异,其实不是JavaScript
,不是HTML/XHTML
和CSS
,而是采用了XMLHttpRequest
来向服务器异步的请求XML
数据。
同步:
异步:
XMLHttpRequest
能够以异步方式的处理程序。Ajax
的原理简单来讲,就是经过XMLHttpRequest
对象来向服务器发送异步请求,从服务器得到数据,而后用javascript
来操做DOM
而更新页面。其中最关键的一步就是从服务器得到请求数据。
一、建立XMLHttpRequest对象:
Ajax
的核心是XMLHttpRequest
对象,它是Ajax
实现的关键,发送异步请求、接受响应以及执行回调都是经过它来完成。
现代浏览器:
全部现代浏览器(IE7+
、Firefox
、Chrome
、Safari
以及Opera
)均内建XMLHttpRequest
对象。
var xhr = new XMLHttpRequest();
老版本IE:
老版本的Internet Explorer
(IE5 和 IE6)使用ActiveX
对象:
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
为了应对全部的现代浏览器,包括IE5
和IE6
,请检查浏览器是否支持XMLHttpRequest
对象。若是支持,则建立 XMLHttpRequest
对象。若是不支持,则建立ActiveXObject
:
兼容性处理:
var xhr = null; if(window.XMLHttpRequest){ // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xhr = new XMLHttpRequest(); }else{ // IE6, IE5 浏览器执行代码 xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
XMLHttpRequest对象的属性和方法:
二、准备请求,设置请求的url等参数:
首先经过open()
方法初始化XMLHttpRequest
对象,接受三个参数:
// 规定请求的类型、URL 以及是否异步处理请求。 xhr.open(method,url,async);
method: 表示的是请求类型的字符串,能够是“GET
”或者“POST
”。
GET请求:
xhr.open("GET","demo.php",true);
POST请求:
xhr.open("POST","demo.php",true);
url: 第二个参数是要做为请求发送目标的URL
。
async: 第三个参数是true
或false
,表示请求是以异步仍是同步的模式发出。(默认为true
,通常不建议为false
)
false
:同步模式发出的请求会暂停全部javascript
代码的执行,直到服务器得到响应为止,若是浏览器在链接网络时或者在下载文件时出了故障,页面就会一直挂起。true
:异步模式发出的请求,请求对象收发数据的同时,浏览器能够继续加载页面,执行其余javascript
代码三、发送请求:
经过XMLHttpRequest
对象的send()
方法,向服务器发送请求。
xhr.send();
GET请求:
通常状况下,使用Ajax
提交的参数多数是些简单的字符串,能够直接使用GET
方法将要提交的参数写到open
方法的url
参数中,此时send
方法的参数为null
或为空。
// get请求是将数据拼接在url后面的 xhr.open("GET",demo.php?name=tsrot&age=24,true); xhr.send(null);
POST请求:
若是须要像HTML
表单那样POST
数据,请使用setRequestHeader()
来添加HTTP
头。而后在send()
方法中规定你但愿发送的数据:
// post请求须要加一个请求头,而且使用send方法将数据进行发送 xhr.open("POST",demo.php,true); xhr.setRequestHeder("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); xhr.send(...);
四、处理响应:
当服务器收到浏览器发送的数据后,会响应一个内容,由于不知道何时数据响应回来,因此提供了一个事件方法onreadystatechange
。每当readyState
改变的时候就会触发onreadystatechange
事件,readyState
属性:存有XMLHttpRequest
的状态信息。
xhr.onreadystatechange = function(){ // 为了保证数据完整回来,咱们通常会判断两个值 if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } }
onreadystatechange
:当处理过程发生变化的时候执行里面的函数
readyState
:ajax
处理过程
0
:请求未初始化(尚未调用 open()
)。1
:请求已经创建,可是尚未发送(尚未调用 send()
)。2
:请求已发送,正在处理中(一般如今能够从响应中获取内容头)。3
:请求在处理中;一般响应中已有部分数据可用了,可是服务器尚未完成响应的生成。4
:响应已完成;您能够获取并使用服务器的响应了。status
状态码属性(详见上面状态码类型):
200
:”OK
”404
: 未找到页面responseText
:得到字符串形式的响应数据;
基本html结构:
<h3>简单的Ajax实例聊天室</h3> <div class="chatbox"> <!-- 聊天记录界面 --> <div class="messages"></div> <!-- 输入界面 --> <div class="form"> <div class="input"><textarea></textarea></div> <div class="btn"> <input type="button" class="send" value="发送"> <input type="button" class="clear" value="清屏"> </div> </div> </div>
js部分:
// 1-发送按钮注册点击事件 var send = document.querySelector(".send"); var clear = document.querySelector(".clear"); var messages = document.querySelector(".messages"); var textarea = document.querySelector(".input").children[0]; send.onclick = function() { // 1-获取输入的内容 动态建立一个p标签 添加到 messages中 var p = document.createElement("p"); var content = textarea.value; if (content != "" && content.trim()) { p.innerText = content + ":Levi"; messages.appendChild(p); p.className = "self"; textarea.value = ""; } // 2-建立Ajax请求 var xhr; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xhr = new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xhr = new ActiveXObject("Microsoft.XMLHTTP"); } xhr.open('post', 'chat.php', true); // post请求的时候,须要使用setRequestHeader()添加响应头 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); xhr.send("message=" + content); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var reply = xhr.responseText; var p = document.createElement("p"); p.innerText = "网友:" + reply; p.className = "other"; messages.appendChild(p); } } } // 3-清屏按钮 clear.onclick = function() { messages.innerHTML = ""; } // 4-回车键触发发送按钮 textarea.onkeydown = function(e) { e = window.event || e; if (e.keyCode == 13) { send.onclick(); e.preventDefault(); } }
PHP部分:
<?php header('Content-Type:text/html;charset=utf-8'); /*建立 对话的队列 */ $message = array( '你好呀!', '干吗?', '我在睡觉。', '上课吧', '骗你的', ); /*随机的取了一句话*/ /*array_rand 去某个数组的随机索引*/ echo $message[array_rand($message)]; sleep(1); ?>
PHP
部分咱们能够不用深究,只须要知道请求的数据message
,在php
里其实就是一个随机字符串。
效果图:
在HTTP
协议中,全部数据最终的传输格式所有都是字符串。若是想要在HTTP
协议中传输一些复杂类型的数据,如数组、对象等,没法直接实现。
后台只有一个,可是开发语言却有不少种,一种后台格式的数据,如何适应所有开发语言的需求呢?因此须要一个统一的数据格式来在各个语言之间传递数据。
XML
(Extensible Markup Language
),可扩展标记语言。它也是一个标记语言,因此它里面也是标签,而且也有文档声明。
XML文件的基本格式:
<!-- 1-声明文档 version:版本 encoding:编码 --> <?xml version = "1.0" encoding="UTF-8"?> <!-- 2-xml必需要有根节点 root--> <root> <!-- name age相对于对象 --> <name>Levi</name> <age>18</age> </root>
注意:
HTML
同样虽然能够描述和传输复杂数据,可是其解析过于复杂而且体积较大,因此实际开发已经使用不多了。
Ajax请求XML数据:
首先,新建一个XML
数据格式的文件-data.xml
:
<?xml version = "1.0" encoding="UTF-8"?> <root> <name>Levi</name> <age>18</age> </root>
新建一个PHP
文件-xml.php
:
<?php // 设置数据解析格式为xml解析方式 header("Content-Type:application/xml"); // 将数据返回给前端 $xml = file_get_contents("data.xml"); echo $xml; ?>
在html
里面经过Ajax
得到数据:
var xhr = new XMLHttpRequest(); xhr.open("get","xml.php"); xhr.send(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status ==200){ console.log(xhr.responseXML); // 返回XML形式的响应数据 // DOM里面的api在xml里面一样适用 console.log(xhr.responseXML.getElementByTagName("name")[0].innerHTML); // 打印 Levi } }
responseXML
:得到XML
形式的响应数据。
在Ajax
中获取到XML
数据以后,须要经过xhr.responseXML
这个属性来获取数据,获取数据的时候能够直接使用DOM
提供的API
。responseText
也能够获取到数据,可是获取到的是字符串,没法经过dom
`api`来操做。
JSON
(JavaScript Object Notation
),是一种轻量级的数据交换格式,独立语言。
json
有别于通常的对象,虽然json
也是键值对的存在,可是json
的键必需要加双引号,而通常的js
对象能够不用加。
json数据的基本格式:
data:[ { "name":"zs", "age":18, "skill":"吹牛" }, ... { "name":"ww", "age":28, "skill":"睡觉" } ]
Ajax请求json数据:
前面咱们知道了,前端在拿后台数据的时候,对后台数据处理提供了两个方法,一个是对字符串处理的responseText
方法,还有一个是对XML
格式处理的responseXML
方法,可是惟独没有处理json
数据的方法,因此咱们须要借助于json
内置对象的JSON.parse
方法,将后台的返回的json
字符串,转换成json
对象。
JSON.parse(xhr.responseText);
新建一个PHP
文件-json.php
:
<?php // 设置数据解析格式为json格式 header("Content-Type:application/json"); $person = array('name' =>'Levi' ,'age'=>18,'skill'=>'帅' ); // json_encode 将对象数据转换成json格式的数据返回前端 echo json_encode($person); ?>
在html
里面经过Ajax
得到数据:
var xhr = new XMLHttpRequest(); xhr.open("get", "01-json.php"); xhr.send(); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { // 前端拿后台数据的时候,只有两种方式 responseText和responseXML // 没有单独为json数据提供一个方法,因此须要将json字符串经过JSON.parse()方法,转换成对象jianrong var jsonStr = xhr.responseText; var jsonObj = JSON.parse(jsonStr); console.log(jsonObj); // 打印的是一个对象 } }
总结方法:
将json
字符串,转换成一个对象:JSON.parse(jsonStr);
// 注意,json字符串里面的属性必须是双引号包裹,单引号包裹会报错 var jsonStr = '{"name":"Levi","age":18,"skill":"帅"}'; var obj = JSON.parse(jsonStr); console.log(obj); // 打印对象 {name: "Levi", age: 18, skill: "帅"}
将对象转换成json
格式的字符串:JSON.stringify;
var obj = { name: "Levi", age: "18", skill: "帅" }; var jsonStr = JSON.stringify(obj); console.log(jsonStr); //打印{"name":"Levi","age":"18","skill":"帅"}
一个页面中,确定不仅是一处须要
ajax
请求,因此咱们能够将它封装成一个函数。
Ajax
对象获取响应头属性:
xhr.getAllResponseHeaders(); // 获取所有响应头信息 xhr.getResponseHeader('key'); // 获取指定头信息
代码封装:
// 封装前须要考虑的因素 // 1- 请求的方式 // get: 须要将数据拼接在url以后 // post: 须要加一个请求头,而且使用send方法将数据进行发送 // 2- 请求的url地址 // 3- 须要发送的数据 // 4- 添加回调函数success,将请求到的数据返回给调用的函数 // 判断服务器返回的是什么格式的数据(经过响应头) // a- xhr.getAllResponseHeaders(); 获取所有响应头信息 // b- xhr.getResponseHeader('key'); 获取指定头信息 function ajax(options) { // 默认值处理 // 设置默认的请求方式为type options.type = options.type || "get"; // 设置默认的请求地址为当前地址栏地址 options.url = options.url || location.href; // 设置默认的请求同步或者异步 options.async = options.async || "true"; // 设置请求参数data的默认值 options.data = options.data || {}; // 处理用户传进来的请求参数(data)对象 var dataArr = []; for (var k in options.data) { dataArr.push(k + "=" + options.data[k]); } var dataStr = dataArr.join("&"); // 异步请求对象兼容性处理 var xhr; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { // IE6及其如下版本 xhr = new ActiveXObjcet('Microsoft.XMLHTTP'); }; // 判断当前的请求方式,若是是get,将数据拼接在地址后面 xhr.open(options.type, options.type == "get" ? options.url + "?" + dataStr : options.url, options.async); // 当是post请求的时候,须要设置请求头 if (options.type == "post") { xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); } // 发送数据,当是post方式的时候,发送数据 xhr.send(options.type == "get" ? null : dataStr); if (options.async) { xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { // 判断请求的数据是什么类型的 var type = xhr.getResponseHeader("Content-Type"); var result; if (type.indexOf("json") != -1) { // 若是是json格式的数据,就将其转换成js对象 result = JSON.parse(xhr.responseText); } else if (type.indexOf("xml") != -1) { // 若是是xml格式的数据,直接返回responseXML result = xhr.responseXML; } else { // 若是两种格式都不是,直接返回responseText result = xhr.responseText; } // 将处理好的数据进行传递 options.success(result); } } } else { // 若是是同步的话就不须要在监测状态改变的状况了 var type = xhr.getResponseHeader("Content-Type"); var result; if (type.indexOf("json") != -1) { result = JSON.parse(xhr.responseText); } else if (type.indexOf("xml") != -1) { result = xhr.responseXML; } else { result = xhr.responseText; } options.success(result); } } // 调用ajax请求 ajax({ url: "json.php", type: "get", data: {name: "levi",age: 18}, success: function(data) { console.log(data); } }); ajax({ url: "xml.php", type: "get", data: {name: "levi",age: 18}, success: function(data) { console.log(data); } });
前面的《jQuery
入门详解》中已经讲到了如何经过jQuery
操做Ajax
,这里再为你们总结一遍。
一、$.ajax()方式经常使用参数解析:
方法 | 做用 |
---|---|
url |
请求的地址 |
type |
请求的方式 |
dataType |
告诉jQuery ,须要按照什么格式对服务器返回的数据进行解析,默认json |
data |
数据 |
success |
请求成功的回调函数 |
error |
请求失败的回调函数 |
beforeSend |
请求发送以前调用的函数 |
complete |
不论请求是成功仍是失败的,只要请求完成就会调用 |
timeout |
设置请求超时时间 |
示例代码:
$.ajax({ // 请求的地址 url: "04-data.php", // 请求的方式 type: "get", // 告诉jQuery,须要按照什么格式对服务器返回的数据进行解析,默认json dataType: "json", // 数据 data: { msg: "我是来请求数据的" }, // 请求成功的回调函数 success: function(data) { console.log(data); }, // 请求失败的回调函数 error: function() { console.log("失败了"); }, // 请求发送以前调用的函数 beforeSend: function() { console.log("请求发送以前调用的函数"); // 若是返回一个false,那么就会阻止整个请求的发送 // return false; // 用法:能够用做表单验证,当表单内容符合规范的时候发送ajax请求,当不符合的时候就不发送ajax请求 }, // 不论请求是成功仍是失败的,只要请求完成就会调用 complete: function() { console.log("请求完成了"); }, // 设置请求超时时间(单位:ms),超过这个时间后,就不会请求了 timeout:2000 });
二、jQuery中的serialize方法:
serialize
方法会将表单中全部的内容拼接成key=value&key=value
这样的字符串。
经过这种方式就不要再去手动获取表单中的内容的
<form id="form"> <input type="text" name="username"> <input type="text" name="pwd"> <input type="text" name="phonenumber"> <input type="text" name="email"> <button id="btn">获取数据</button> </form> <script src="jquery.min.js"></script> <script> $(function() { $('#btn').click = function() { var dataStr = $('#form').serialize(); $.ajax({ url: "json.php", //data这个参数能够接收对象,也能够接受 key=value&key=value的这种字符串 data: dataStr, type: "post" }); } }); </script>
三、jQuery中的serializeArray方法:
上面的方法咱们能够看到,获取整个数据的时候,是很简单,可是想要进行校验的话就很难,由于上面的方法获取的是一个字符串,不能进行校验,因此此时咱们须要另一个方法,jQuery
中的serializeArray
方法。
<form id="form"> <input type="text" name="username"> <input type="text" name="pwd"> <input type="text" name="phonenumber"> <input type="text" name="email"> <button id="btn">获取数据</button> </form> <script src="jquery.min.js"></script> <script> $(function() { $('#btn').click = function() { // 获取到的数组拼接成字符串 var dataArr = $('#form').serializeArray(); $.ajax({ url: "json.php", data: dataArr, type: "post" }); } }); </script>
示例代码:ajax模拟表单校验及注册
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>sing in page</title> <style> body { margin: 0; padding: 0; background-color: #F7F7F7; } ul { margin: 0; padding: 50px; list-style: none; } .register { width: 800px; margin: 50px auto; background-color: #FFF; border: 1px solid #CCC; border-radius: 5px; } li { display: flex; margin: 20px 0; } label, input { display: block; float: left; height: 46px; font-size: 24px; box-sizing: border-box; color: #333; } label { width: 200px; line-height: 46px; margin-right: 30px; text-align: right; } input { width: 320px; padding: 8px; line-height: 1; outline: none; position: relative; } input.code { width: 120px; } input.verify { width: 190px; margin-left: 10px; } input.disabled { background-color: #CCC !important; } input[type=button] { border: none; color: #FFF; background-color: #E64145; border-radius: 4px; cursor: pointer; } .error { color: red; margin-left: 10px; font-size: 12px; line-height: 46px; } .tips { position: fixed; top: 0; width: 100%; height: 40px; text-align: center; } .tips p { min-width: 300px; max-width: 400px; line-height: 40px; margin: 0 auto; color: #FFF; display: none; background-color: #C91623; } </style> </head> <body> <div class="register"> <form id="ajaxForm"> <ul> <li> <label for="name">用户名</label> <input type="text" name="name" class="name" id="name"> <span class="error"></span> </li> <li> <label for="pass">请设置密码</label> <input type="password" name="pass" class="pass" id="pass"> </li> <li> <label for="repass">请确认密码</label> <input type="password" name="repass" class="repass" id="repass"> </li> <li> <label for="mobile">验证手机</label> <input type="text" name="mobile" class="mobile" id="mobile"> </li> <li> <label for="code">短信验证码</label> <input type="text" name="code" class="code" id="code"> <input type="button" value="获取验证码" class="verify"> </li> <li> <label for="submit"></label> <input type="button" class="submit" value="当即注册" id="submit"> </li> </ul> </form> </div> <div class="tips"> <p>用户名不能为空</p> </div> <script src="../05-Form-Validation/js/jquery.min.js"></script> <script> /* * 1.获取短信验证码 * 1.1 当没有输入手机号的时候 提示请输入手机号 * 1.2 手机号格式不正确 提示请输入正确的手机号 * 1.3 调获取短信验证码接口 * 1.4 显示正在发送中 不能再次发送(防止重复提交) * 1.5 当接口成功 按照后台的计时时间 进行倒计时 * 1.6 当接口失败 提示短信接口繁忙 恢复按钮 * 1.7 倒计时完成以后 恢复按钮 * */ /* * 2.注册 * 2.1 当没有输入用户名的时候 提示请输入用户名 * 2.2 调注册接口 * 2.3 显示正在提交 不能再次发送(防止重复提交) * 2.4 当接口成功 * 状态码 10000 成功 * 状态码 10001 失败 提示用户 用户名已注册 表单后 * 状态码 10002 失败 没输用户 请输入用户名 * 恢复按钮 * 2.5 当接口失败 恢复按钮 * */ $(function() { /* 警告显示提示 */ var showTip = function(tip) { $(".tips p").html(tip).fadeIn(500).delay(1000).fadeOut(500); }; /* 1.获取短信验证码 */ $(".verify").on("click", function() { /* 当前按钮指定变量 */ var $btn = $(this); /* 判断当前按钮是否有disabled属性,有的话说明已经被点击了,就不让再点击了 */ if ($btn.hasClass('disabled')) { return false; } /* 获取手机号 */ var mobile = $.trim($('#mobile').val()); /* 判断是否输入内容,没有的话提示信息 */ if (!mobile) { showTip('请输入手机号'); return false; } /* 判断手机格式 不正确的话提示信息 */ var regPhone = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/; if (!regPhone.test(mobile)) { showTip('请输入正确的手机号'); return false; } /* 调取短信验证码接口 */ $.ajax({ url: 'registerCode.php', type: 'post', dataType: 'json', data: { mobile: mobile }, success: function(data) { if (data.code == 10000) { /* 给发送成功的按钮添加一个倒计时 */ var time = parseInt(data.result.time); var timer = setInterval(function() { time--; $btn.val(time + '秒后再次获取'); /* 倒计时完成以后 恢复按钮*/ if (time <= 0) { $btn.val('获取验证码').removeClass('disabled'); clearInterval(timer); } }, 1000); } else { /* 逻辑上的失败 */ $btn.val('获取验证码').removeClass('disabled'); } }, error: function() { /* 当接口失败,提示短信接口繁忙 */ showTip('短信接口繁忙'); $btn.val('获取验证码').removeClass('disabled'); }, beforeSend: function() { /* 点击以后,显示正在发送 */ $btn.val('正在发送...').addClass('disabled'); } }); $btn.addClass('disabled'); }); /* 2.注册功能的实现 */ $('.submit').on('click', function() { /* 当前点击的按钮 */ var $btn = $(this); /* 正在请求当中 不能再次点击 */ if ($btn.hasClass('disabled')) { return false; } var username = $("#name").val().trim(); var password = $("#pass").val().trim(); var repeatPassword = $("#repass").val().trim(); var code = $("#code").val().trim(); var phoneNum = $("#mobile").val().trim(); /* 调注册接口 */ $.ajax({ type: 'post', url: 'register.php', data: { name: username, pass: password, repass: repeatPassword, code: code, mobile: phoneNum }, dataType: 'json', // beforeSend: function() { // /* 显示正在提交 不能再次发送(防止重复提交)*/ // $btn.val('正在提交...').addClass('disabled'); // }, success: function(data) { /* 当接口成功 */ /* 状态码 10000 成功 */ if (data.code == 10000) { /* 提示+跳转登陆页 */ showTip('恭喜' + data.result.name + '注册成功,3后秒自动前往登陆页'); setTimeout(function() { location.href = 'http://www.baidu.com/'; }, 3000); } else if (data.code == 10001) { /* 输入框提示 */ $('.error').html('用户名已注册'); /* 恢复按钮 */ $btn.val('当即注册').removeClass('disabled'); } else if (data.code == 10002) { showTip('请输入用户名'); /* 恢复按钮 */ $btn.val('当即注册').removeClass('disabled'); } }, error: function() { showTip('系统繁忙!'); $btn.val('当即注册').removeClass('disabled'); } }) }); }); </script> </body> </html>
效果图:
模板引擎,就是将一段已经写好模板,使用数据进行填充以后生成
html
。
一、引入模板引擎插件:
<script src="template-web.js"></script>
二、建立script
标签,注意类型是type="text/template"
,而且要有一个id
,模板内部是须要渲染的内容:
<script type="text/template" id="tpl"> <div>我叫 </div> <div>我今年 岁</div> </script>
三、调用template
方法,将数据渲染到模板内:
var obj = { name:"Levi", age:18 } // template("模板的id",要将什么数据渲染到模板中) var html = template("tpl",obj);
四、回到上面的模板部分,在里面添加占位符:
<script type="text/template" id="tpl"> // {{}} ==> 就是占位符 // name 和 age 对应的就是对象obj里面的两个属性 <div>我叫{{name}}</div> <div>我今年{{age}}岁</div> </script>
五、打印调用的字符串:
var html = template("tpl",obj); console.log(html); // 打印的就是div字符串
一、$data:
模板一级特殊变量可使用
$data
,指的就是获取的数据;
<!-- 能够经过$data拿到 template函数传进来的数据 --> {{$data["name"]}}
二、条件语句:
{{if value}}...{{/if}} {{if value1}}...{{else if value2}}...{{/if}}
示例:
<!-- 注意结束必需要有{{/if结尾}} --> {{if age >= 18}} <div>我成年了</div> {{else}} <div>我没有成年了</div> {{/if}}
三、循环语句:
$index
指的是获取当前遍历的索引值;$value
指的是获取当前遍历的元素。
{{each target}} {{$index}} {{$value}} {{/each}}
示例:
<script type="text/template" id="tpl"> {{each idol}} <!--$index 获取当前遍历的索引--> <!--$value 获取当前正在遍历的元素--> <div>第{{$index}}号偶像:{{$value.name}}</div> {{/each}} </script> <script> var obj = { name: "Levi", age: 18, idol:[ {name : "刘德华"}, {name : "张学友"}, {name : "古天乐"} ] } var html = template("tpl", obj); // 引入jQuery $('body').append(html); </script>
效果图:
注意:这里介绍一个语法as v i
,能够手动指定$index
和$value
的量
<script type="text/template" id="tpl"> {{each idol as v i}} <!--i 获取当前遍历的索引--> <!--v 获取当前正在遍历的元素--> <div>第{{i}}号偶像:{{v.name}}</div> {{/each}} </script>
四、变量:
<!--能够在模板引擎中声明变量--> {{set temp = data.content}}
示例:
<script type="text/template" id="tpl"> <!-- 设置一个变量val 用来接收数据的name值 --> {{set val = name}} <!-- 打印的就是对象的name属性对应的值 --> {{val}} </script> <script> var obj = { name: "Levi", age: 18, idol:[ {name : "刘德华"}, {name : "张学友"}, {name : "古天乐"} ] } var html = template("tpl", obj); // 引入jQuery $('body').append(html); </script>
五、标签“@”的用法:
当一个标签在页面以字符串形式显示的时候,加上“
@
”后就会当成标签去解析。
首先根据后台数据,动态建立一个信息表格:
前端渲染:
<button id="btn">获取数据生成表格</button> <script type="text/template" id="tpl"> <table width="600" border="1"> <thead> <tr> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>头像</th> </tr> </thead> <tbody> <!-- $data 是个一级变量,表示的就是返回的数据 --> {{each $data as v i}} <tr> <td>{{v.name}}</td> <td>{{v.age}}</td> <td>{{v.gender}}</td> <td>{{v.avatar}}</td> </tr> {{/each}} </tbody> </table> </script> <script src="template-web.js"></script> <script> $(function() { // 点击按钮,发送Ajax请求 $("#btn").click(function() { $.ajax({ url: "tableData.php", type: "get", success: function(data) { var htmlStr = template("tpl", data); $("body").append(htmlStr); } }); }); }); </script>
后台数据:
<?php header("Content-Type:application/json;charset=utf-8"); echo '[{"name": "小乔", "age": 18, "gender": "male", "avatar": "<img src=\"1.jpg\" />"}, {"name": "大乔", "age": 18, "gender": "female", "avatar": "<img src=\"1.jpg\" />"}, {"name": "甄姬", "age": 18, "gender": "male", "avatar": "<img src=\"1.jpg\" />"}]'; ?>
根据上面的代码,咱们能够动态生成一个表格:
看到问题所在了,在后台请求回来的图片地址直接以字符串的形式渲染到页面上了。
解决办法:只须要在头像占位那一栏里面加一个@
符号
{{each $data as v i}} <tr> <td>{{v.name}}</td> <td>{{v.age}}</td> <td>{{v.gender}}</td> <td>{{@v.avatar}}</td> </tr> {{/each}}
再看效果图:
此时头像就能够显示了。
一、原生语法:
<%= name %>
二、原生语法判断语句:
<%= if(age == 18){ %> <div>我满18岁了</div> <% } %>
三、原生语法循环语句:
<% for(var i = 0; i < arr.length; i++){ %> <!-- 遍历数据数组arr,将它里面的name属性显现出来 --> <div><%= arr[i].name %></div> <% } %>
json
数据模拟后台数据:
{ "code": 200, "msg": "OK", "result": [{ "tc_id": "193", "tc_name": "一代天骄葫芦娃", "tc_roster": "攻城狮", "tc_gender": "1", "tc_cellphone": "", "tc_email": "", "tc_status": "0", "tc_birthday": "1970-01-01", "tc_join_date": "2017-06-15" }, { "tc_id": "194", "tc_name": "用爱感化司马ad", "tc_roster": "攻城狮", "tc_gender": "0", "tc_cellphone": "", "tc_email": "", "tc_status": "0", "tc_birthday": "1970-01-01", "tc_join_date": "1970-01-01" } ] }
html
页面Ajax
请求部分:
<!-- 引入jQuery --> <script src="jquery.min.js"></script> <!-- 引入模板引擎 --> <script src="template-web.js"></script> <!-- 模板引擎渲染数据 --> <script type="text/template" id="tpl"> <table> <thead> <tr> <th>序号</th> <th>昵称</th> <th>性别</th> <th>生日</th> <th>花名</th> </tr> </thead> <tbody> {{each $data.result as v i}} <tr> <!-- 序号从1开始,因此就是遍历的下标加1 --> <td>{{i + 1}}</td> <!-- 昵称 --> <td>{{v.tc_name}}</td> <!-- 后台数据返回的是数字字符串。判断下以男女显示 --> <td>{{if v.tc_gender == "1"}}男{{else}}女{{/if}}</td> <!-- 生日 --> <td>{{v.tc_birthday}}</td> <!-- 花名 --> <td>{{v.tc_roster}}</td> </tr> {{/each}} </tbody> </table> </script> <script> $(function() { $.ajax({ url: "teacher.json", type: "get", success: function(data) { // 通常后台都会提供接口文档,能够知道数据的名字,也能够直接打印数据在控制台中查看 console.log(data); // 当数据成功返回以后,将数据以表格的形式打印在页面当中 if (data.code == 200) { var htmlStr = template("tpl", data); $('body').append(htmlStr); } } }); }); </script>
效果图:
经过后台提供的图片信息,以及图片连接,动态的生成瀑布流。
首先须要后台提供的接口文档:
接口地址:waterfull.php 请求方式:get 接口参数:page:当前是第几页 pageSize:当前页面须要显示数据的条数 返回类型:json 返回数据:{page: 2,items:[{path:"./images/0011.jpg",text:"文本信息"}...]} page:下一页的页码 items:返回当前页的数据 path:图片地址 text:图片下方的文本
后台程序以及数据(仅攻参考,不是前端的活):
waterfull.php:
<?php header('Content-Type:text/html; charset=utf-8'); /*获取数据 字符串*/ $data = file_get_contents('data.json'); /*转化php对象? 须要对其操做*/ $data = json_decode($data); /*页码*/ $page = $_GET['page']; /*条数*/ $pageSize = $_GET['pageSize']; /*获取数据的起始索引*/ $offset = ($page - 1) * $pageSize; /*slice 从什么位子开始切割 切割多少条*/ $result = array_slice($data, $offset, $pageSize); /*下一页的页码*/ $page++; /*转化json字符串 输出到前端*/ echo json_encode(array('page'=>$page, 'items'=>$result));/*{items:[]}*/ /*延时1秒返回数据*/ sleep(1); ?>
data.json:
[ { "path": "./images/001.jpg", "text": "一支素笔,一杯花茶,一段时光,浅笑又安然一场盛世的繁华,愿不倾城,不倾国,只倾我全部。只为过简单安稳的生活,单纯不平凡。一支素笔,一杯花茶,一段时光,浅笑又安然。早安!" }, ... { "path": "./images/100.jpg", "text": "青春,青春,一场盛世不平凡。一支素笔,一杯花茶,一段时光,浅笑又安然一场盛世的繁华,愿不倾城,不倾国,只倾我全部。只为过简单安稳的生活,单纯不平凡。一支素笔,一杯花茶,一段时光,浅笑又安然。早安!" } ]
Ajax请求后台数据,动态渲染瀑布流:
Ajax请求数据:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>瀑布流</title> <style> body { margin: 0; padding: 0; font-family: "Microsoft Yahei"; background: #f5f5f5; } .box { width: 1200px; margin: 0 auto; padding-top: 40px } .box > .items { position: relative; } .box > .items > .item { width: 220px; box-shadow: 2px 2px 2px #999; position: absolute; } .box > .items > .item > p { margin: 0; padding: 10px; background: #fff; } /*目的是固定高度且不同*/ .box > .items > .item > img { width: 100%; display: block; height: px; } /*目的是固定高度且不同*/ .box > .items > .item:nth-child(4n) > img { width: 100%; display: block; height: 450px; } .box > .btn { width: 280px; height: 40px; margin: 30px auto; text-align: center; line-height: 40px; background-color: #CCC; border-radius: 6px; font-size: 24px; cursor: pointer; } .box > .loading { background-color: transparent; } </style> </head> <body> <div class="box"> <div class="items"> </div> <div class="btn">加载更多</div> </div> <script type="text/template" id="tpl"> {{each items as v i}} <div class="item"> <img src="{{v.path}}" alt=""> <p>{{v.text}}</p> </div> {{/each}} </script> <script src="jquery.min.js"></script> <script src="jquery.waterfull.js"></script> <script src="template-web.js"></script> <script> // ajax 请求,一进来先调用一次 function render(){ $.ajax({ url:"waterfull.php", type:"get", dataType:"json", data:{ // 3-首先去按钮中,找下一页的page属性,若是没有的话,给一个默认值1 page:$(".btn").data("page") || 1, pageSize: 15 }, success:function(data){ var htmlStr = template("tpl",data); $(".items").append(htmlStr); $(".items").waterfull(); // 1-将请求回来的数据中表示下一页的页码page存入btn的自定义属性data-page中 // 2-给按钮加上一个自定义属性page 值就是后台返回的page属性 // 7-当数据加载完以后,还要将按钮变成正在加载,而且要移除disabled这个类 $(".btn").data("page",data.page).text("加载更多").removeClass("disabled"); // 8-数据是有限的,假如请求不到数据以后,须要将按钮置成disabled,而且加上文字“没有更多数据了” if(data.items.length == 0){ $(".btn").text("没有更多数据了").addClass("disabled"); } } }); } render(); // 4-点击加载更多的时候,调用Ajax请求 $(".btn").click(function(){ // 6- 一进来县普安段一下按钮有没有disabled这个类,若是有的话让它不能够被点击 if($(this).hasClass("disabled")){ return false; } render(); // 5-点击按钮以后改变按钮的状态,和文本 $(this).text("正在加载中"); $(this).addClass("disabled"); }); </script> </body> </html>
其中jquery.waterfull.js
为封装的jQuery
瀑布流插件:
(function() { $.fn.waterFull = function() { //1. 肯定一共多少列 var columns = 5; //2. 获取每个元素的宽度 var width = this.children().width(); //3. 计算间隔 var space = (this.width() - width * columns) / (columns - 1); //声明数组来保存每一列当前的高度 var heightArr = []; this.children().each(function(index, ele) { //4. 为第一行的元素设置定位 if (index < columns) { $(ele).css({ top: 0, left: index * (width + space), }); heightArr.push($(ele).height()); } else { //除过第一行以外的全部的内容 //先计算当前全部列中最短的列 var minHeight = heightArr[0]; var minIndex = 0; $.each(heightArr, function(index, value) { if (minHeight > value) { minHeight = value; //找到了最短的列所在的索引 minIndex = index; } }) //将当前要摆放的元素的高度累加到当前列所对应的高度中 heightArr[minIndex] += $(ele).height() + space; //就是最短列的高度加上间隔 var top = minHeight + space; //由于已经找到了要把当前元素放在哪一列 //因此直接使用列的索引计算便可 var left = minIndex * (width + space); $(ele).css({ top: top, left: left, }) } //5. 将items的高度设置为最高的那一列的高度 var maxHeight = heightArr[0]; $.each(heightArr, function(index, value) { maxHeight = maxHeight > value ? maxHeight : value; }) console.log($(this)); $(this).parent().height(maxHeight) }); } })()
效果图:
除了手动点击按钮以外,咱们还能够监听滚动条的位置,当在底部的时候直接调用加载函数:
$(window).scroll(function(){ // 获取滚动条当前滚动的距离 var scrollTop = $(this).scrollTop(); // 获取整个盒子的高度 var boxHeight = $(".box").outerHeight(); // 获取可视区的高度 var windowHeight = $(window).height(); // 判断当滚动条的高度大于等于盒子的高度减去可视区的高度的时候,调用加载函数 if(scrollTop >= boxHeight - windowHeight){ // 请求数据还须要判断下有没有disabled这个类,没有的时候才能加载 if(!$(".btn").hasClass("disabled")){ render(); $(".btn").text("正在获取数据").addClass("disabled"); } } });
Postman
是一款模拟Ajax
请求的软件,根据接口文档,输入请求地址,以及选择请求的方式,再输入须要请求的数据,就能模拟从后台,获取到数据。
根据图片的注释,咱们能够大体了解这款软件的用法,根据接口文档填上信息,点击右上角send
,就会模拟发送Ajax
请求,response
返回请求的结果。
同源策略最初是在1995年时提出,到目前为止全部浏览器都实行这个政策。
最初它的含义是指,A网页设置的
Cookie
,B网页不能打开,除非这两个网页"同源",所谓同源就是必需要知足三个条件:
举个例子:
http://www.abc.com/home/index.html
这个网址中,协议是http://
,域名是www.abc.com
,端口是80
(默认端口能够省略),下面看几个例子:
URL | 说明 | 是否容许通讯 |
---|---|---|
http://www.a.com/a.html <br/>http://www.a.com/b.html |
协议、域名、端口都相同 | 容许 |
http://www.a.com/a/a.html <br/>http://www.a.com/b/b.html |
协议、域名、端口都相同,不一样文件夹下 | 容许 |
http://www.a.com/a.html <br/>http://www.a.com:8000/b.html |
协议、域名相同,端口不一样 | 不容许 |
http://www.a.com/a.html <br/>https://www.a.com/b.html |
域名、端口相同,协议不一样 | 不容许 |
http://www.a.com/a.html <br/>https://www.b.com/b.html |
协议、端口相同,域名不一样 | 不容许 |
http://www.a.com/a.html <br/>http://70.32.92.74/b.html |
协议、端口相同,域名和域名对应ip | 不容许 |
同源策略的目的就是为了保护用户信息安全,防止恶意的网站窃取数据。
打个比方,你登陆了某个网站A
,同时你又去浏览了另外一个网站B
,若是B
网站可以读取你A
网站里存储的cookie
,会发生什么?你在A
网站里面的信息,将会被泄露,更可怕的是,cookie
每每用来保存用户的登陆状态,若是用户没有退出登陆,B
网站就能够冒充用户进行操做。因此“同源策略”是必须得。
随着互联网的发展,“同源策略”愈来愈严格。目前若是非同源,共有三种行为受到限制:
(1) Cookie、LocalStorage 和 IndexDB 没法读取。 (2) DOM 没法得到。 (3) AJAX 请求不能发送。
虽然这些限制是必要的,可是有时很不方便,合理的用途也受到影响。
同源策略规定,
Ajax
请求只能发给同源的网址,不然就报错。
XHR
对象进行跨域请求会直接被浏览器制止html
一些标签中的src
属性也能够发送请求,至关因而发送了一个get
请求src
属性中书写的地址,发送出去的请求,是不会受到浏览器同源策略的限制的下面介绍三种解决跨域的方法
JSONP
是服务器与客户端跨源通讯的经常使用方法,最大的特色就是简单适用。老式浏览器所有支持,服务器改造很是小。
实现原理:
jsonp
的原理就是:动态的建立一个script
标签,将这个script
标签的src
属性设置为要请求的地址url
,将script
标签添加到页面以后,src
属性会自动向url
发送一个get
请求,又因为,后台返回的数据格式比较特殊,是一个函数调用的语句,因此咱们提早定义好一个函数,那么这个函数就会在请求成功以后自动被调用,数据也会被传入到这个函数中,最终就相似于ajax
请求的回调的效果!
<script> // url即请求的地址,赋值给动态建立的script标签的src属性 function creatScriptTag(url,callback){ // 一个页面可能会有不少跨域请求,若是回调函数名写死,那么只能用一次 // 随机生成一个函数名,将回调函数以这个随机生成的名字命名 var callbackName = "jsonp" + new Data().getTime() + parseInt(Math.random() * 1000); // 将回调函数添加到window对象中,相似于添加了一个这个随机函数名的一个全局函数 window[callbackName] = callback; var script = document.createElement('script'); script.setAttribute('type','text/javascript'); // 注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。 script.src = url + "?callback=" + callbackName; document.body.appendChild(script); } creatScriptTag("http://api.ajax.com/data.php", function(data){ console.log(data); }) </script>
jQuery里的JSONP:
在jQuery
中,发送Ajax
方法的时候,只要定义一个dataType:"jsonp"
,便可实现跨域。
WebSocket
是一种通讯协议,正常是由后台操控,使用ws://
(非加密)和wss://
(加密)做为协议前缀。该协议不实行同源政策,只要服务器支持,就能够经过它进行跨源通讯。
下面是一个例子,浏览器发出的WebSocket
请求的头信息。
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com
上面代码中,有一个字段是Origin
,表示该请求的请求源(origin
),即发自哪一个域名。
正是由于有了Origin
这个字段,因此WebSocket
才没有实行同源政策。由于服务器能够根据这个字段,判断是否许可本次通讯。若是该域名在白名单内,服务器就会作出以下回应。
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat
(本篇完)