Ajax
浏览器的组成
- 用户界面(User Interface)
- 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分
- 浏览器引擎(Browser engine)
- 用来查询及操作渲染引擎的接口
- 渲染引擎(浏览器内核)(Rendering engine)
- 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来
- 主流的渲染引擎
- Chrome浏览器: Blink引擎(WebKit的一个分支)。
- Safari浏览器: WebKit引擎,windows版本2008年3月18日推出正式版,但苹果已于2012年7月25日停止开发Windows版的Safari。
- FireFox浏览器: Gecko引擎。
- Opera浏览器: Blink引擎(早期版使用Presto引擎)。
- Internet Explorer浏览器: Trident引擎。
- Microsoft Edge浏览器: EdgeHTML引擎(Trident的一个分支)。
- 渲染引擎工作原理
- 解析HTML构建Dom树,DOM 是W3C组织推荐的处理可扩展置标语言的标准编程接口。
- 构建渲染树,渲染树并不等同于Dom树,因为像
head
标签 或display: none
这样的元素就没有必要放到渲染树中了,但是它们在Dom树中。 - 对渲染树进行布局,定位坐标和大小、确定是否换行、确定position、overflow、z-index等等,这个过程叫
layout
或reflow
。 - 绘制渲染树,调用操作系统底层API(UI Backend)进行绘图操作。
- JS解释器(JavaScript Interpreter)
- 用来解释执行JS代码
- 网络(Networking)
- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
- UI后端(UI Backend)
- 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口
- 数据存储(Data Persistence)
- 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了Storage技术,这是一种轻量级完整的客户端存储技术
服务器
服务器软件
使计算机具备提供某种服务能力的应用软件,称为服务器软件,通过安装相应的服务软件,然后进行配置后就可以使计算具备了提供某种服务的能力。
- 文件服务器:Server-U、FileZilla、VsFTP等(FTP是File Transfer Protocol文件传输协议);
- 数据库服务器:oracle、mysql、SQL server、DB2、ACCESS等;
- 邮件服务器:Postfix、Sendmail等;
- HTTP服务器:Apache、Nginx、IIS、Tomcat、NodeJS等;
服务器类型
- 按服务类型可分为:文件服务器、数据库服务器、邮件服务器、Web服务器等;
- 按操作系统可分为:Linux服务器、Windows服务器等;
- 按应用软件可分为 Apache服务器、Nginx 服务器、IIS服务器、Tomcat服务器、weblogic服务器、WebSphere服务器、boss服务器、 Node服务器等;
HTTP服务器
前端打交道的服务器;
- 即网站服务器,主要提供文档(文本、图片、视频、音频)浏览服务,一般安装Apache、Nginx服务器软件。
- HTTP服务器可以结合某一编程语言处理业务逻辑,由此进行的开发,通常称之为服务端开发。
- 常见的运行在服务端的编程语言包括 php、java、.net、Python、Ruby、Perl等。
服务器总结
- 服务器说白了就是计算机,通过安装了某些软件,就可以提供某些特定的服务器。
- 根据服务器软件的功能,名称,安装的系统这些不同的标准,可以对服务器划分成不同的类型。
- HTTP服务器主要提供网站浏览服务,通常需要结合某种编程语言进行开发,我们通常称之为服务器开发。
- 专业的服务器与计算机的区别
- 稳定性:服务器要求7*24不间断运行。
- 性能:服务器能够同时响应更多客户端的请求。
- 价格:服务器价格通常比普通计算机贵很多。
客户端
具有向服务器索取服务能力的终端,叫做客户端。
客户端:电脑、平板、手机安装了客户端软件,就可以称为客户端
浏览器===>索取网站服务浏览的软件
- 对于前端工程师而言,主要接触到的客户端软件就是浏览器,当然也可能会涉及大一些app开发。
- 以浏览器为宿主环境,结合 HTML、CSS、Javascript等技术,而进行的一系列开发,通常称之为前端开发。
服务器与客户端的关系
- 客户端:安装客户端软件,索取服务的一方
- 服务器:安装服务器软件,提供服务的一方
软件架构
CS架构
Client/Server架构,即客户端/服务器架构。是大家所熟悉的软件体系结构。需要安装对应的客户端软件,才能获取相应的服务。
常见的CS架构:QQ、LOL、微信等
特点:
- 需要安装才是使用
- 性能高效,使用更加稳定和流畅
- 开发和维护难度更大。
- 需要更新
- 需要兼容操作系统。
BS架构
- 不需要安装,只需要浏览器即可。
- 相比CS架构,性能相对较差,没有那么流畅和稳定。
- 开发维护方便。
- 不需要更新
- 不用兼容操作系统。但是需要兼容浏览器。
搭建HTTP服务器
phpStudy介绍
phpStudy是一个PHP调试环境的程序集成包。
该程序包集成最新的Apache+PHP+MySQL,安装非常的简单
phpStudy的安装
安装phpStudy,解压双击安装(非中文路径),其它默认安装。
推荐就安装在默认的目录下,一定不能有中文,否则肯定启动不起来。
phpStudy的错误解决
- 关闭iis服务器
- 提示缺少vc9 库文件
- 关闭防火墙
- 新版的phpStudy需要设置
1 | You don't have permission to access |
网络基础
ip地址
所谓IP地址就是给每个连接在互联网上的主机分配的一个32位地址。(就像每部手机能正常通话需要一个号码一样)
通过ip就可以找到具体的某一台计算机。例 192.168.1.110
查看本机IP地址
1 | ping、ipconfig、ifconfig(linux) |
端口
- 端口号是计算机与外界通讯交流的出口,每个端口对应不同的服务。
- 现实生活中,银行不同的窗口办理不同的业务。
- 查看端口占用情况
netstat -an
- 常见端口号 80(http)、403(https)、21(ftp文件传输协议)、22(ssh远程登录协议)
域名
由于IP地址基于数字,不方便记忆,于是便用域名来代替IP地址,域名是一个IP地址的“面具”;每一个域名都会对应了至少一个ip地址。
查看域名对应的IP地址 ping
1 | ping jd.com //可以获取到京东的ip |
DNS服务器
DNS(Domain Name System)因特网上作为域名和IP地址相互映射的一个分布式数据库, 能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
简单的说就是记录IP地址和域名之间对应关系的服务。
本地hosts
Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。
hosts文件的地址:C:\Windows\System32\drivers\etc
浏览器访问流程
- 浏览器通过域名访问网页,
- 先查找本地hosts文件,如果有对应域名的ip的地址,就直接访问这个ip地址;
- 如果本地hosts文件没有对应的ip地址,就访问DNS服务器,获取到域名对应的ip地址,访问这个ip地址;
- 访问ip对应的服务器,服务器响应,返回这个请求;
例如京东
1 | jd.com:80/index.html |
http服务端口默认为80
PHP基础
- 文件以.php后缀结尾,所有程序包含在
<?php 这里是代码 ?>
- 避免使用中文目录和中文文件名
- php页面无法直接打开需要运行在服务器环境当中
注意:学习php的目的是辅助学习ajax,因为我们需要了解一点后台的知识,千万不要本末倒置的跑去学习php语法。
PHP初体验
语法:<?php ?>
- PHP语法中结束必须在末尾加;号,否则会报错;最后一句可以省略(没啥用);
- 服务器解析PHP文件中的中文以gbk编码解析;浏览器以UTF-8编码,会出现乱码;
header("content-Type:text/html;charset=utf-8");
content-Type:text/html;
返回内容是一个HTML文档,这样设置后,就能识别HTML标签了。charset=utf-8
设置编码集- 中文不会乱码,识别HTML标签;
PHP
PHP变量
php是一门弱类型语法,变量的类型可以随意改变。变量其实就是存储数据的容器;
变量命名规则
- 不需要关键字进行声明,变量在第一次赋值的时候被创建。
- 必须以$符号开始
- $后面的命名规则与js的变量命名规则一致。
数据类型
- 字符串
- 数字
- 浮点型
- 布尔类型,如果打印,true显示为1,false显示为空串;实际还是布尔类型;
1 | $flag = true; |
php中+号只是数学运算符,不能用来拼串;
1 | // 1. 在php中,+号只有算数的功能,并不能拼串 |
用.拼串
php中””和’’不同,””识别其中包含的变量;’’不能识别;
1 | //1. 字符串的定义可以使用单引号,也可以使用双引号 |
PHP数组
索引数组–类似js中的数组;
1 | $arr = array("张飞","赵云","马超"); |
关联数组–类似js中的对象;
1 | //属性名必须用引号引起来 |
获取数组的长度:count($arr)
输出语句
echo
输出简单数据类型print_r
输出数据结构,一般用于输出复杂类型。print_r
是一个函数,不要忘记小括号var_dump
输出完整的数据结构,包括类型,一般用于精准调试
语句
判断语句
1 | $age = 17; |
循环语句
遍历索引数组
1 | $arr = array("张三", "李四", "王五", "赵六", "田七", "王八"); |
遍历关联数组
1 | //遍历关联数组 |
表单处理
表单(form):表单用于收集用户输入信息,并将数据提交给服务器。是一种常见的与服务端数据交互的一种方式
- action:指定表单的提交地址
- method:指定表单的提交方式,get/post,默认get
- input的数据想要提交到后台,必须指定name属性,后台通过name属性获取值
- 想要提交表单,不能使用
input:button
必须使用input:submit
php获取表单数据
$_GET
是系统提供的一个变量,是一个数组,里面存放了表单通过get方式提交的数据。
$_POST
是系统提供的一个变量,是一个数组,里面存放了表单通过post方式提交的数据。
get与post的区别
- get方式
1.1 数据会拼接在url地址的后面?username=hcc&password=123456
1.2 地址栏有长度限制,因此get方式提交数据大小不会超过4k - post方式
2.1 数据不会在url中显示,相比get方式,post更安全
2.2 提交的数据没有大小限制
根据HTTP规范,GET用于信息获取,POST表示可能修改变服务器上的资源的请求
文件上传
html要求
- 文件上传的提交方式必须是post方式
- 需要给form指定enctype=”multipart/form-data”
- 指定name属性,后台才能获取到
php相关
文件上传时,$_GET与$_POST都无法获取到文件信息,通过$_FILES才能获取到,这是一个数组。
上传文件时,文件会临时保存在服务器上,如果文件最终没有保存,那么临时文件会被删除,保证服务器安全。
sleep(10)可以让代码延迟10秒钟才执行。
1 | move_uploaded_file($path, $newPath); //可以保存临时图片 |
服务端渲染
动态页面与静态页面
- 静态页面:静态页面的内容和结构都是写死的,不会变化的,实实在在存在服务器上的html文件;
- 动态页面:页面的内容会根据后台数据实时生成的,结构根据新生成的内容发生变化,存在服务端是一个php或者jsp文件,根据用户访问的时候,实时动态变化;
服务端渲染页面
前端程序员将静态页面写好以后,交给后端开发人员,由后端开发人员根据数据库内容动态渲染,叫做服务端渲染;
以前很长一段时间的开发模式就是这样的,前端工程师先把html页面写好,后端程序员把html页面后缀改成(php)(jsp)(asp)页面,然后将数据渲染出来。
1 |
|
服务端渲染总结
- 我们使用php动态渲染页面时,有很多比较麻烦的地方。
- 在前端写好页面以后,需要后台进行修改,意味这后端程序员也需要懂前端的知识,其实渲染的工作应该交给前端来做。
- 前端没有写好页面的话,后端无法开始工作,需要等待前端的页面完成之后才能开始工作,拖延项目的进度。
- 这种渲染,属于同步渲染,页面加载速度比较慢,会影响后面的内容的渲染速度。
http协议
协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则
HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和服务器之间互相通信的规则,HTTP协议分为请求 和响应 两个部分组成。
请求与请求报文
get请求报文详解
1 | //--------------------------请求行-------------------------------- |
post请求报文详解
1 | //-----------------------请求行--------------------------------------------- |
GET请求与POST请求的对比
- GET请求没有请求体,因为GET请求的参数拼接到地址栏中了
- POST请求有请求体,就是传递的参数
- POST请求需要指定
content-type
属性。
响应与响应报文
响应报文详解
1 | //---------------------状态行(响应行)------------------------------- |
通常来说,我们不会用抓包工具来查看请求和响应,太麻烦了,可以直接使用谷歌浏览器来查看请求报文和响应报文。
谷歌浏览器会对报文进行一定的格式化,看起来虽然不是原生的报文,但是使用起来更加的方便简洁。
pre标签
<pre></pre>
被包围在 pre
元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。
常见应用就是用来表示计算机的源代码。
Ajax详解
即 Asynchronous [e’sɪŋkrənəs] Javascript And XML, AJAX 不是一门的新的语言,而是对现有技术的综合利用。 本质是在HTTP协议的基础上以异步的方式与服务器进行通信。
同步与异步
同步和异步概念:
- 同步: 指的就是事情要一件一件做。等做完前一件才能做后一件任务
- 异步: 不受当前任务的影响,两件事情同时进行,做一件事情时,不影响另一件事情的进行。
编程中:异步程序代码执行时不会阻塞其它程序代码执行,从而提升整体执行效率。
网页异步应用:
- 验证你的用户名是否已经存在(一边输入,一边获取你的信息,和后台比对)。
- 百度搜索提示,及相关内容展示(一边输入,一边找出了你可能要的内容)。
- 新浪微博评论(异步加载)。
XMLHttpRequest
Ajax不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
浏览器内建对象,用于与服务器通信(交换数据) , 由此我们便可实现对网页的部分更新,而不是刷新整个页面。这个请求是异步,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。
创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest();
构造函数没有参数或者不传参数,可以不要括号;
发送请求
发送get请求
- 设置请求行:
xhr.open("get","地址?参数&参数");
–get是把参数拼接到地址后面的; - 设置请求头:get不用设置请求头大部分的请求头都是由浏览器自动完成的;
- 设置请求体:
xhr.send(null);
get的参数是拼接到请求行的地址后面;参数设置为null;请求体必须设置,表示请求设置完毕,发送请求;
1 | // 使用XMLHttpRequest发送get请求的步骤 |
- get请求,设置请求行时,需要把参数列表拼接到url后面
- get请求不用设置请求头
- get请求的请求体为null
发送post请求
- 设置请求行:
xhr.open("post","地址");
–post参数不会拼接到地址后面,设置在请求体; - 设置请求头:
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
–post必须设置; - 设置请求体:
xhr.send("参数1&参数2");
– 参数用&隔开;
1 | var xhr = new XMLHttpRequest; |
- post请求,设置请求行时,参数列表不能拼接到url后面
- post必须设置请求头中的
content-type
为application/x-www-form-urlencoded
- post请求需要将参数列表设置到请求体中.
同步与异步
xhr.open("get","地址",布尔类型)
–默认为true,异步执行;设置为false时,同步执行;
获取响应
readystatechange事件:监听XMLHttpRequest对象状态;发生改变时触发;
xhr.readyState
- readyState:记录了XMLHttpRequest对象的当前状态
- 请求未初始化。发生在创建XMLHttpRequest对象之后;
- 请求已经建立,但是还没有开始发送。发生在设置请求头之后;
- 请求已发送,正在处理中;理论上发生在请求体之后,但是需要时间,所以不是即时生效;
- 请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
- 响应已完成;您可以获取并使用服务器的响应了。(我们只需要关注状态4即可)
响应行:xhr.status
- http状态码
- 200表示成功
- 304表示读缓存
- 404表示找不到资源
- 500表示服务端错误
响应头
xhr.getAllResponseHeaders();
–获取响应头所有信息;xhr.getResponseHeader("content-type");
–获取响应头指定的信息;
响应体:xhr.responseText
1 | xhr.onreadystatechange = function() { |
数据交互
浏览器端只是负责用户的交互和数据的收集以及展示,真正的数据都是存储在服务器端的。我们现在通过ajax的确可以返回一些简单的数据(一个字符串),但是在实际开发过程中,肯定会会涉及到大量的复杂类型的数据传输,比如数组、对象等,但是每个编程语言的语法都不一样。因此我们会采用通用的数据交换格式(XML、JSON)来进行数据的交互。
对于大量复杂数据交互,用通用的数据格式来传输数据;
XML(重量级)
- XML 指可扩展标记语言(EXtensible Markup Language)
- XML 是一种标记语言,很类似 HTML
- XML 的设计宗旨是传输数据,而非显示数据
- XML 标签没有被预定义。您需要自行定义标签。
语法规范
- 必须有一个根元素(有且仅有一个)
- 标签不可有空格、不可以数字或.开头、大小写敏感
- 不可交叉嵌套,都是双标签,如果是单标签,必须闭合
- 属性双引号(浏览器自动修正成双引号了)
- 注释和HTML一样
1 | <students> |
php获取xml文件的内容
注意,如果需要返回xml数据,需要把content-type
改成text/xml
,不然浏览器以text/html
进行解析。
1 |
|
html解析xml
服务端返回的数据需要使用xhr.responseXML
,这是一个document对象,可以使用DOM中的方法查找元素。
1 | //获取服务端返回的xml数据,需要使用xhr.responseXML,这是一个document对象,可以使用DOM中的方法查找元素。 |
缺点:虽然可以描述和传输复杂数据,但是其解析过于复杂并且体积较大,所以实现开发已经很少使用了。
JSON数据(轻量级)
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript 规范的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
- 数据在名称/值对中
- 数据由逗号分隔(最后一个健/值对不能带逗号)
- 花括号保存对象,方括号保存数组
- 键使用双引号
json实际是字符串,数据传输的是字符串;
1 | var obj = {a: 'Hello', b: 'World'}; //这是一个js对象,注意键名也是可以使用引号包裹的 |
- JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
- 不同的语言各自也都对应有解析方法,需要解析完成后才能读取
- JSON 和 JS 对象之间互转
json与js对象的相互转换
1 | // JS对象 ==> JSON字符串 `JSON.stringify(obj)` |
php处理json
php关联数组 ==> json
1 | // php的关联数组 |
json ===> php对象
1 | $json = '{"a": "Hello", "b": "World"}';//json字符串 |
eval方法
eval()
函数可计算某个字符串,并执行其中的的 JavaScript 代码。eval的参数是一个字符串,这个字符串是需要执行的表达式或者语句。
eval函数的功能非常的强大,但是实际使用的情况并不多。
- eval形式的代码难以阅读
- eval形式的代码无法打断点,因为本质还是还是一个字符串
- 在浏览器端执行任意的 JavaScript会带来潜在的安全风险,恶意的JavaScript代码可能会破坏应用
1 | // eval方法可以直接转换字符串数组,但是对象则有些特殊; |
jQuery的Ajax方法
$.ajax({obj})
- type:请求类型;
- url:请求地址;
- data:请求发送的参数;可以是字符串,可以是对象,
- 表单序列化,这两个方法data能够直接识别;
$("form").serialize()
–会把form表单中所有有name属性的name值和value值都拼接起来;返回一个字符串;$("form").serializeArray()
–会把form表单中所有有name属性的name值和value值都拼接起来;返回一个数组;
- dataType:服务器响应返回的数据格式,不传递会根据数据的content-type进行判定;
- timeout:超时时间,服务器在时间内没有响应,会判定响应失败;单位毫秒;
- success:服务器响应成功调用的函数;
- error:服务器响应失败调用的函数;
- beforeSend:发送请求前调用的函数;
- complete:请求完成后的回调函数;不管响应成功还是失败,都能执行;
$.post(url,data,success,dataType);
–post请求;$.get(url,data,success,dataType);
–get请求;$.getJSON(url,data,success);
–请求载入服务器上指定url的JSON文件;$.getScript(url,data,success);
–请求载入服务器上指定url的js文件;$("div").load(url,data,success);
–在div中载入服务器上指定url的html页面。- 可以用来加载公共页面
- 缺点是会额外加载引入的页面
接口化开发
请求地址即所谓的接口,通常我们所说的接口化开发,其实是指一个接口对应一个功能, 并且严格约束了请求参数 和响应结果 的格式,这样前后端在开发过程中,可以减少不必要的讨论, 从而并行开发,可以极大的提升开发效率,另外一个好处,当网站进行改版后,服务端接口进行调整时,并不影响到前端的功能。
接口文档
实现前后端分离
模板引擎
是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。 数据+模版 = 最终需要显示的结构(动态);
我们通过ajax获取到数据后,需要把数据渲染到页面,在学习模板引擎前,我们的做法是大量的拼接字符串,对于结构简单的页面,这么做还行;
但是如果页面结构很复杂,使用拼串的话代码可阅读性非常的差,而且非常容易出错,后期代码维护也是相当的麻烦。
常见的模板引擎
- BaiduTemplate:http://tangram.baidu.com/BaiduTemplate/
- velocity.js:https://github.com/shepherdwind/velocity.js/
- ArtTemplate:https://github.com/aui/artTemplate
artTemplate的使用
- 引入模板引擎的js文件
- 准备模板:写死的静态页面;
- 准备数据:从后端获取动态数据;
- 使用template方法将模板和数据绑定;
- 使用artTemplate语法修改模板;
- 渲染到页面中;
- artTemplate的each语法:
- 如果返回的数据是个数组,必须使用对象进行包裹,因为在{{}}中只写书写对象的属性。
- 模板中可以直接使用对象的属性, 如果返回的数据直接就是一个数组。
- 注意:如果直接是一个数组的话,需要使用对象包裹一下,给数组起了一个名字
- artTemplate的中文文档:https://aui.github.io/art-template/zh-cn/docs/syntax.html
完整版代码
- 指定了type为text/html后,这一段script标签并不会解析,也不会显示。
1 |
|
同源与跨域
同源
同源策略是浏览器的;
1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。所谓”同源”指的是”三个相同”。
同源必须保证三个一致
- 协议相同
- 域名相同
- 端口相同
举例来说,http://www.example.com/dir/page.html 这个网址,协议是http://
,域名是www.example.com
,端口是80(默认端口可以省略)。它的同源情况如下。
1 | //http://www.example.com/dir2/other.html:同源 |
同源策略的目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
某用户是网站A的管理员,用户只要登录网站A并且执行删除用户的操作就可以把网站A中的其他用户删除。当这个用户访问了网站A之后,又访问了一个网站B,这时候如果网站B可以获取到网站A的cookie,那么网站B就能伪造该用户的身份去访问网站A,即网站B也可以执行相同的操作去删除网站A中的其他用户,那这样带来的后果是不堪设想的。
CSRF攻击(跨站请求伪造),因此同源策略是必须的,如果cookie可以在不同源的网站中共享,那么互联网将毫无安全可言。
同源策略的限制范围
虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域 。
- 随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
跨域
JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。原理:服务端返回一个预先定义好的javascript函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。
特殊标签是不受同源策略限制的
script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有img和link标签 ;
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>
script标签src引入
- jsonp的原理:script标签引入文件不受同源策略限制;
- script标签src引入的文件会执行,最后返回给浏览器的都是字符串;因此script可以引入php文件;
- 所以通过PHP文件返回的数据会被script标签引入时执行;
- 后端返回一个函数调用,将数据当做函数的实参传入;在script标签引入的时候会执行这个函数;
- 前端提前声明一个函数,设置形参,通过后端返回的函数调用可以获取到数据;
- jsonp前后端约定,通过callback把声明的函数名传递给后端,后端通过这个函数名返回函数调用;
- 后端把json数据包裹后返回,就叫做jsonp(JSON with Padding);
jsonp演化过程1
php文件
1 | header("content-type:text/html;charset=utf-8"); |
html文件 <script src="http://www.api.com/testjs.php"></script>
原理:其实src的路径是什么文件不重要,无论引入js文件还是php文件,最后返回给浏览器的都是字符串,因此我们script标签是可以引入一个php文件的。
jsonp演化过程2
php文件
1 | header("content-type:text/html;charset=utf-8"); |
html文件
1 | <script src="http://www.api.com/testjs.php"></script> |
我们现在做到了一件事情,从不同源的php文件中获取到了数据;
缺点:获取数据的script标签必须写在使用的script标签的前面,必须保证先有数据才能对数据进行渲染。
jsonp演化过程3
php代码
1 | header("content-type:text/html;charset=utf-8"); |
js代码
1 | <script> |
缺点:后端必须知道前端声明的方法的名字,后端才能调用。
jsonp演化过程4
php代码
1 | header("content-type:text/html;charset=utf-8"); |
javascript代码
1 | function fun(data) { |
说白了,jsonp的原理就是 借助了script标签不受同源策略的限制,在服务端返回一个函数的调用,将数据当前调用函数的实参。在浏览器端,需要程序要声明一个函数,通过形参就可以获取到服务端返回的对应的值。
$.ajax({dataType:"jsonp"});
- jQuery的ajax方法只要指定dataType为”jsonp”,就可以跨域获取数据;
- jsonp和ajax没有任何关系,不是通过ajax交互的;
- jQuery通过script标签引入数据后,会删除这个script标签;
- script标签src引入,对后台发送的是get请求;
jsonp的函数封装
1 | function jsonp(url, fn) { |
1 |
|
1 | jsonp("http://192.168.34.31/day05/003-data.php", function (info) { |
XMLHttpRequest2.0
XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。
XMLHttpRequest1.0
- 仅支持传输文本数据,无法传输二进制文件,比如图片视频等。
- 传输数据时,没有进度信息,只能提示完成与否。
- 受到了”同源策略”的限制
XMLHttpRequest2.0
我们现在使用new XMLHttpRequest创建的对象就是2.0对象了,我们之前学的是1.0的语法,现在学习一些2.0的新特性即可。
可以设置timeout超时时间
1 | xhr.timeout = 3000;//设置超时时间 |
可以使用formData对象管理表单数据(好用)
- formData对象类似于jquery的serialize方法,用于收集表单数据;
var formData = new FormData(form);
- 参数:form是一个表单元素;收集此表单内的数据;
- 参数可以不传递,默认是一个空的表单元素
- formData对象可以直接作为
xhr.send(formData)
的参数。注意此时数据是以二进制的形式进行传输。 - formData有一个append方法,可以添加额外参数。
formData.append("id", "1111");
- 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。
1 | //1. 使用formData必须发送post请求 |
允许请求不同域名下的数据(跨域)
跨域资源共享(CORS)
新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做”跨域资源共享”(Cross-origin resource sharing,简称CORS)。
浏览器支持这个功能(现在的浏览器都支持了XMLHttpRequest2.0)
服务器必须允许这种跨域。
1 | // 服务器允许跨域的代码: |
CORS的具体流程
- 浏览器会向发送一条请求,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了header(‘Access-Control-Allow-Origin:请求源域名或者*’);
- 如果没有设置,说明服务器不允许使用cors跨域,那么浏览器会把获取到的数据拦截。
- 如果返回的响应头中设置了
header('Access-Control-Allow-Origin:请求源域名或者*');
,浏览器会跟请求头中的Origin: http://www.study.com
进行对比,如果满足要求,就把数据发送给用户。 - 结论:跨域行为是浏览器行为,是浏览器阻止了ajax行为。服务器与服务器之间是不存在跨域的问题的
jsonp与cors的对比
jsonp兼容性好,老版本浏览器也支持,但是jsonp仅支持get请求,发送的数据量有限。使用麻烦;
cors需要浏览器支持cors功能才行。但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的get、post请求并没有什么区别。
跨域的安全性问题:很多同学会觉得跨域能带来安全性问题,其实并不会,因为跨域是需要服务端配合的 ,也就是说不论jsonp还是cors,如果没有服务端的允许,浏览器是没法做到跨域的。
其他的跨域手段(没卵用)
以下方式基本不用啊,了解即可:
- 顶级域名相同的可以通过domain.name来解决,即同时设置
domain.name = 顶级域名(如example.com)
document.domain
+ iframewindow.name
+ iframelocation.hash
+ iframewindow.postMessage()
支持上传二进制文件,支持异步上传文件
以前,文件上传需要借助表单进行上传,但是表单上传是同步的,也就是说文件上传时,页面需要提交和刷新,用户体验不友好,xhr2.0中的formData对象支持文件的异步上传。
1 | <input type="file" id="img"> |
1 |
|
可以获取数据传输的进度信息
xhr2.0还支持获取上传文件的进度信息,因此我们可以根据进度信息可以实时的显示文件的上传进度。
- 需要注册
xhr.upload.onprogress = function(e){}
事件,用于监听文件上传的进度.注意:需要在send之前注册。 - 上传的进度信息会存储事件对象e中
- e.loaded表示已上传的大小 e.total表示整个文件的大小
1 | <input type="file" id="img"> |
1 |
|
如果上传文件超过8M,php会报错,需要进行设置,允许php上传大文件。
修改php.ini文件
- 允许提交的最大数据:663行,
post_max_size = 8M
- 允许上传的最大的文件为2M:791行,
upload_max_filesize = 2M
分页插件 bootstrap-paginator
依赖与bootstrap的一款插件
引包 <script src="lib/bootstrap-paginator/bootstrap-paginator.js"></script>
提供一个ul作为分页的容器
1 | <!-- 显示分页 --> |
初始化分页
1 | $("#paginator").bootstrapPaginator({ |
#