标签:形参 不发送 响应 语言 根据 上传 children 这一 服务端
我们使用php动态渲染页面时,有很多比较麻烦的地方。
【演示:同步渲染】
HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和服务器之间互相通信的规则
HTTP协议规定了请求 和响应 的标准
get请求的请求报文详解
//--------------------------请求行--------------------------------
// GET 请求方式
// /day02/01.php?username=pp&password=123456 请求路径+参数(注意点)
// HTTP/1.1 HTTP的版本号
GET /day02/01.php?username=pp&password=123456 HTTP/1.1
//--------------------------请求头--------------------------------
Host: www.study.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
//----------------------------请求体-------------------------------------
//get请求没有请求体,但是参数会拼接到请求行中
POST请求的请求报文
//-----------------------请求行---------------------------------------------
POST /day02/01.php HTTP/1.1
//-----------------------请求头--------------------------------------------
Host: www.study.com
Connection: keep-alive
//传递的参数的长度。
Content-Length: 29
Cache-Control: max-age=0
Origin: http://www.study.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
//内容类型:表单数据,如果是post请求,必须指定这个属性。
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Referer: http://www.study.com/day02/01-login.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
//------------------------请求体------------------------------------------
username=pp&password=123456
GET请求与POST请求的对比
//---------------------状态行(响应行)-------------------------------
//HTTP/1.1 HTTP版本
//200 响应的状态
//200表示成功
//304表示读缓存
//404表示找不到资源
//500表示服务端错误
HTTP/1.1 200 OK
//----------------------响应头-----------------------------------------------
Date: Thu, 22 Jun 2017 16:51:22 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Content-Length: 18
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
//内容类型,告诉浏览器该如何解析响应结果
Content-Type: text/html;charset=utf-8
//-----------------------响应体------------------------------------------------
hello world
即 Asynchronous [e‘s??kr?n?s] Javascript And XML, AJAX 不是一门的新的语言,而是对现有技术的综合利用。 本质是在HTTP协议的基础上以异步的方式与服务器进行通信。
同步和异步概念:
同步: 指的就是事情要一件一件做。等做完前一件才能做后一件任务
异步: 不受当前任务的影响,两件事情同时进行,做一件事情时,不影响另一件事情的进行。
编程中:异步程序代码执行时不会阻塞其它程序代码执行,从而提升整体执行效率。
网页异步应用:
XMLHttpRequest可以以异步方式的请求数据处理程序, 可实现对网页的部分更新, 而不是刷新整个页面
浏览器内建对象,用于与服务器通信(交换数据) , 由此我们便可实现对网页的部分更新,而不是刷新整个页面。这个请求是异步的,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。
请求由客户端发起,其规范格式为:请求行、请求头、请求主体。
XMLHttpRequest以异步的方式发送HTTP请求,因此在发送请求时,一样需要遵循HTTP协议。
使用XMLHttpRequest发送get请求的步骤
//1. 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//2. 设置请求行
// 第一个参数:请求方式 get/post
// 第二个参数:请求的地址 需要在url后面拼上参数列表
xhr.open("get", "01.php?name=Jepson");
//3. 设置请求头
//请求头中可以设置Content-Type,用以说明请求主体的内容是如何编码,get请求时没有请求体,无需设置
//4. 设置请求体
//get请求的请求体为空,因为参数列表拼接到url后面了
xhr.send(null);
注意点 :
var xhr = new XMLHttpRequest();
// 1. 设置请求行 post请求的参数列表在请求体
xhr.open("post", "02.php");
// 2. 设置请求头, post 请求必须要设置 content-type, 标记请求体内容的解析方式, 不然后端无法解析获取数据
xhr.setRequestHeader( "content-type", "application/x-www-form-urlencoded" );
// 3. 设置请求体
xhr.send( "name=Jepson&age=18" );
注意点 :
readyState:记录了XMLHttpRequest对象的当前状态
readyState有五种可能的值:
xhr.readyState = 0时,UNSENT open尚未调用
xhr.readyState = 1时,OPENED open已调用
xhr.readyState = 2时,HEADERS_RECEIVED 接收到头信息
xhr.readyState = 3时,LOADING 接收到响应主体
xhr.readyState = 4时,DONE 响应完成
不用记忆状态,只需要了解有状态变化这个概念
HTTP响应分为3个部分,状态行、响应头、响应体。
//给xhr注册一个onreadystatechange事件,当xhr的状态发生状态发生改变时,会触发这个事件。
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
//1. 获取状态行
console.log("状态行:"+xhr.status);
//2. 获取响应头
console.log("所有的响应头:"+xhr.getAllResponseHeaders());
console.log("指定响应头:"+xhr.getResponseHeader("content-type"));
//3. 获取响应体
console.log(xhr.responseText);
}
}
【判断用户名是否存在】
【用户登录案例】
【聊天机器人案例】
浏览器端只是负责用户的交互和数据的收集以及展示,真正的数据都是存储在服务器端的。
我们现在通过ajax的确可以返回一些简单的数据(一个字符串),
但是在实际开发过程中,肯定会会设计到大量的复杂类型的数据传输,
比如数组、对象等,但是每个编程语言的语法都不一样。
因此我们会采用通过的数据交换格式(XML、JSON)来进行数据的交互。
什么是XML
语法规范
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student>
<name>张三</name>
<age>18</age>
<gender>男</gender>
<desc>路人甲</desc>
</student>
<student>
<name>李四</name>
<age>20</age>
<gender>男</gender>
<desc>路人乙</desc>
</student>
</students>
php获取xml文件的内容
// 注意: 如果需要返回 xml 数据, 需要将 content-type 改成 text/xml, 不然浏览器以 text/html 解析
header( 'content-type:text/xml;charset=utf-8' );
// file_get_content 用于获取文件的内容
// 参数: 文件的路径
$result = file_get_content( "data.xml" );
echo $result;
js解析xml
//获取服务端返回的xml数据,需要使用xhr.responseXML,这是一个document对象,可以使用DOM中的方法查找元素。
var data = xhr.responseXML;
//获取所有的学生
var students = data.querySelectorAll("student");
缺点:虽然可以描述和传输复杂数据,但是其解析过于复杂, 并且体积较大,所以实现开发已经很少使用了。
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript 规范,采用独立于编程语言的文本格式来存储和表示数据。
var obj = {a: 'Hello', b: 'World'}; //这是一个对象
// 这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}';
JSON数据在不同语言进行传输时,类型为字符串,不同的语言各自也都对应有解析方法,解析完成后就能很方便的使用了
// php的关联数组
$obj = array(
"a" => "hello",
"b" => "world",
"name" => "鹏鹏"
);
//json字符串
$json = json_encode( $obj );
echo $json;
$json = '{"a": "Hello", "b": "World"}';//json字符串
//第一个参数:json字符串
//第二个参数:
//false,将json转换成对象(默认)
//true:将json转换成数组(推荐)
$obj = json_decode($json,true);
echo $obj['a'];
//通过json文件获取到的内容就是一个json字符串。
$data = file_get_contents("data.json");
//将json转换成数组
$result = json_decode($data, true);
print_r($result);
//obj是一个js对象
var obj = {a: 'Hello', b: 'World'}
//result就变成了一个json字符串了
var result = JSON.stringify(obj);// '{"a": "Hello", "b": "World"}'
//json是一个json字符串
var json = '{"a": "Hello", "b": "World"}';
//obj就变成了一个js对象
var obj = JSON.parse(json);// {a: 'Hello', b: 'World'}
使用json进行数据传输
思考:
【案例:获取表格数据.html】
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。eval的参数是一个字符串,这个字符串是需要执行的表达式或者语句。
console.log(eval("{}"));//undefined,因为{}备当成了代码块
console.log(eval("({})"));//obj,因为{}用()引起来了。
//使用这个方法,也可以将一个json字符串转换成js对象。
var json = '{"name":"zs", "age":18, "sex":"男"}';
var obj = eval("(" + json + ")");
console.log(obj);
注意:eval函数的功能非常的强大,但是实际使用的情况并不多。
现在一般最多兼容到 IE8, 这里以后见到了知道是在处理兼容性就行了
var xhr = null;
if(XMLHttpRequest){
//现代浏览器 IE7+
xhr = new XMLHttpRequest();
}else{
//老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
每次发送ajax请求,其实步骤都是一样的,重复了大量代码,我们完全可以封装成一个工具函数。
//1. 创建xhr对象
//2. 设置请求行
//3. 设置请求头
//3. 设置请求体
//4. 监听响应状态
//5. 获取响应内容
参数名 | 参数类型 | 描述 | 传值 | 默认值 |
---|---|---|---|---|
type | string | 请求方式 | get/post | 只要不传post,就是get |
url | string | 请求地址 | 接口地址 | 如果不传地址,不发送请求 |
async | boolean | 是否异步 | true/fase | 只要不传false,那就是true,异步请求 |
data | object | 请求数据 | {key:value,key1:value2} |
需要把这个对象拼接成参数的格式 uname=hucc&upass=12345 |
dataType | string | 返回的数据类型 | xml/json/text | text |
success | function | 响应成功时调用 | - | - |
error | function | 响应失败时调用 | - | - |
// 要求参数obj必须传递,否则直接不发送请求
if(!obj || typeof obj !== "object"){
return;
}
// 如果type传递的是post,那就发送post请求,否则发送get请求
var type = obj.type == "post"?"post":'get';
var url = obj.url;
if(!url){
return;
}
// 只有当async传递了false,才会发送同步请求,不然只发送异步请求
var async = obj.async == false? false:true;
// 封装 ajax
// 目的: 发送 get 或者 post 请求
// 参数:
// type: 不传post, 就按get处理
// url: 必须传
// async: 不传false, 就按true处理
// data: 参数对象
// dataType: 数据类型, json/xml/text
// success: 成功的回调函数
// error: 失败的回调函数
// 命名空间: 将函数收录到一个对象中, 将来通过对象调用函数
var $ = {
ajax: function (options) {
// 参数处理
if (!options || typeof options != "object") { // 没传或者不是对象
return;
}
var type = options.type === "post" ? "post" : "get"; // 默认get
var url = options.url;
if (!url) {
return;
}
var async = options.async === false ? false : true; // true
var data = options.data; // 参数对象, 需要转换
var params = this.parse(data); // $.ajax => 方法调用模式, 谁调用方法, this就指向谁
var dataType = options.dataType;
var success = options.success;
var error = options.error;
// 发送请求
var xhr = new XMLHttpRequest();
if (type === "get") {
// 需要拼接参数
url = url + "?" + params;
params = null;
}
xhr.open(type, url, async);
// post请求需要设置请求头
if (type === "post") {
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
}
xhr.send(params);
// 监听, 处理响应
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // 响应完成
if (xhr.status === 200) { // 响应成功
// 返回来的格式可能不一样
var result = null;
if (dataType === "xml") {
result = xhr.responseXML;
}
else if (dataType === "json") {
result = JSON.parse(xhr.responseText);
}
else {
result = xhr.responseText;
}
success && success(result);
}
else { // 响应失败
error && error(xhr.responseText);
}
}
}
},
parse: function (obj) {
if (!obj || typeof obj != "object") {
return null;
}
var arr = [];
for (var k in obj) {
arr.push(k + "=" + obj[k]); // name=pp
}
return arr.join("&");
}
};
【登录案例】
jQuery为我们提供了更强大的Ajax封装
参数列表
参数名称 | 描述 | 取值 | 示例 |
---|---|---|---|
url | 接口地址 | url:"02.php" | |
type | 请求方式 | get/post | type:"get" |
timeout | 超时时间 | 单位毫秒 | timeout:5000 |
dataType | 服务器返回的格式 | json/xml/text(默认) | dataType:"json" |
data | 发送的请求数据 | 对象 | data:{name:"zs", age:18} |
beforeSend | 调用前的回调函数 | function(){} | beforeSend:function(){ alert(1) } |
success | 成功的回调函数 | function (data) {} | success:function (data) {} |
error | 失败的回调函数 | function (error) {} | error:function(data) {} |
complete | 完成后的回调函数 | function () {} | complete:function () {} |
使用示例:
$.ajax({
type:"get",//请求类型
url:"02.php",//请求地址
data:{name:"zs", age:18},//请求数据
dataType:"json",//希望接受的数据类型
timeout:5000,//设置超时时间
beforeSend:function () {
//alert("发送前调用");
},
success:function (data) {
//alert("成功时调用");
console.log(data);
},
error:function (error) {
//alert("失败时调用");
console.log(error);
},
complete:function () {
//alert("请求完成时调用");
}
});
【案例:登录案例.html】
//$.post(url, callback, [dataType]);只发送post请求
//$.get(url, callback, [dataType]);
//$.getJSON(url, callback);
//$.getScript(url,callback);//载入服务器端的js文件
//$("div").load(url);//载入一个服务器端的html页面。
请求地址即所谓的接口,通常我们所说的接口化开发,其实是指一个接口对应一个功能, 并且严格约束了请求参数 和响应结果 的格式,这样前后端在开发过程中,可以减少不必要的讨论, 从而并行开发,可以极大的提升开发效率,另外一个好处,当网站进行改版后,服务端接口进行调整时,并不影响到前端的功能。
需求文档(产品)
总需求:点击获取验证码按钮,向服务端发送请求, 调用服务器端短信接口, 服务器端根据传参, 调用第三方短信接口, 给手机发送验证码
需求1:格式校验
(1) 手机号码不能为空 如果为空提示"手机号不能为空"
(2) 手机号码格式必须正确, 提示"请输入正确的手机号码"
需求2:点击发送时,按钮显示为"发送中",并且不能重复提交请求
需求3:根据不同的响应结果,进行响应。
(1)如果接口调用成功
如果响应代码为100,倒计时
如果响应代码为101,提示手机号重复
(2)如果接口调用失败,告诉用户"服务器繁忙,请稍候再试"
接口文档
接口说明:获取短信验证码
接口地址:getCode.php
请求方式:get
接口传参:mobile 手机号
返回类型 json
接口返回:{
"code":"101",
"msg":"手机号码存在",
"mobile":"18511249258"
}
参数说明: code 当前业务逻辑的处理成功失败的标识 100:成功 101:手机号码存在
msg 当前系统返回给前端提示
mobile 当前的手机号码
表单序列化 serialize
jquery提供了一个serialize()
方法序列化表单,说白就是将表单中带有name属性的所有参数拼成一个格式为name=value&name1=value1
这样的字符串。方便我们获取表单的数据。
//serialize将表单参数序列化成一个字符串。必须指定name属性
//name=pp&pass=123456&repass=123456&mobile=15751776629&code=1234
$('form').serialize();
jquery的ajax方法,data参数能够直接识别表单序列化的数据
$.post({
url:"register.php",
data:$('form').serialize(),
dataType:'json',
success:function (info) {
console.log(info);
}
});
需求文档
注册功能
总需求:点击注册按钮,向服务端发送请求
需求1:表单校验
1.1 用户名不能为空,否则提示"请输入用户名"
1.2 密码不能为空,否则提示"请输入密码"
1.3 确认密码必须与密码一直,否则提示"确认密码与密码不一致"
1.4 手机号码不能为空,否则提示"请输入手机号码";
1.5 手机号码格式必须正确,否则提示"手机号格式错误"
1.6 短信验证码必须是4位的数字,否则提示"验证码格式错误"
需求2:点击注册按钮时,按钮显示为"注册中...",并且不能重复提交请求
需求3:根据不同响应结果,处理响应
3.1 接口调用成功
100 提示用户注册成功,3s后跳转到首页
101 提示用户"用户名jepson已经存在"
102 提示用户"验证码错误"
3.2 接口调用失败,提示"服务器繁忙,请稍后再试",恢复按钮的值
接口文档
接口说明:注册
接口地址:register.php
请求方式:post
接口传参:name:用户名 pass:密码 code:验证码 mobile:手机号
返回类型 json
接口返回:{
"code":"100",
"msg":"注册成功",
"name":"Jepson"
}
参数说明:
code 当前业务逻辑的处理成功失败的标识 100:成功 101:用户存在 102:验证码错误
msg 当前系统返回给前端提示
name: 注册的用户名
是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
我们通过ajax获取到数据后,需要把数据渲染到页面,在学习模板引擎前,我们的做法是大量的拼接字符串,对于结构简单的页面,这么做还行
但是如果页面结构很复杂,使用拼串的话代码可阅读性非常的差,而且非常容易出错,后期代码维护也是相当的麻烦。
【演示:使用拼串进行渲染的缺点.html】
总结来说拼串渲染两大缺点:
BaiduTemplate:http://tangram.baidu.com/BaiduTemplate/
velocity.js:https://github.com/shepherdwind/velocity.js/
ArtTemplate:https://github.com/aui/artTemplate
artTemplate是使用最广泛,效率最高的模板引擎,需要大家掌握。
1.引入模板引擎的js文件
<script src="template-web.js"></script>
2.准备模板
<!--
指定了type为text/html后,这一段script标签并不会解析,也不会显示。
-->
<script type="text/html" id="myTmp">
<p>姓名:隔壁老王</p>
<p>年龄:18</p>
<p>技能:查水表</p>
<p>描述:年轻力气壮</p>
</script>
3.准备数据
//3. 准备数据,数据是后台获取的,可以随时变化
var json = {
userName:"隔壁老王",
age:18,
skill:"查水表",
desc:"年轻气壮"
}
4.将模板与数据进行绑定
//第一个参数:模板的id
//第二个参数:数据
//返回值:根据模板生成的字符串。
var html = template("myTmp", json);
console.log(html);
5.修改模板
<script type="text/html" id="myTmp">
<p>姓名:{{userName}}</p>
<p>年龄:{{age}}</p>
<p>技能:{{skill}}</p>
<p>描述:{{desc}}</p>
</script>
6.将数据显示到页面
var div = document.querySelector("div");
div.innerHTML = html;
if语法
{{if gender='男'}}
<div class="man">
{{else}}
<div class="woman">
{{/if}}
each语法
<!--
1. {{each data}} 可以通过$value 和 $index获取值和下标
2. {{each data v i}} 自己指定值为v,下标为i
-->
{{each data v i}}
<li>
<a href="{{v.url}}">
<img src="{{v.src}}" alt="">
<p>{{v.content}}</p>
</a>
</li>
{{/each}}
//如果返回的数据是个数组,必须使用对象进行包裹,因为在{{}}中只写书写对象的属性。
var html = template("navTmp", {data:info});
/**
* 实现思路分析:
* 1. 找到父容器, 获取父容器宽度
* 2. 找到子容器, 获取子容器宽度, 一行排 5 个
* 3. 根据父容器, 子容器的以及列数, 计算间隔 (space) 间隔: (父容器宽 - 子容器宽 * 列数) / (列数 - 1);
* 4. 遍历子元素, 设置子元素的位置
*
* 初始化一个高度数组 arr = [0, 0, 0, 0, 0];
*
* 第一行:
* left: 索引值 * (子元素宽度 + 间隔)
* top: 0
*
* 其他行:
* left: 数组中最小值的索引 * (子元素宽 + 间隔)
* top: 数组中最小值 + 间隔
*
* 5. 更新数组中的最小值, 加上添加的元素的高和间隔
*/
$(function() {
// 1. 获取父元素和子元素, 以及他们的宽高
var $box = $('.box');
var $items = $box.children();
var boxWidth = $box.width(); // 获取父元素的宽度
var itemWidth = $items.width(); // 获取子元素的宽度
var columns = 5; // 一行排 5 个元素
// 2. 计算间隔
var space = (boxWidth - itemWidth * columns) / (columns - 1); // 10
// 3. 遍历排放子元素
var arr = [ 0, 0, 0, 0, 0 ]; // 初始化数组
$items.each(function( index, element ) {
if ( index < columns ) {
// (1) 先排第一行, 索引值为 0 1 2 3 4的
$(this).css({
left: index * ( itemWidth + space ),
top: 0
});
// 将各个盒子高度按顺序更新到数组中
arr[index] = $(this).height();
}
else {
// (2) 其他行, 找最小列高度 和 最小列索引
var min = arr[ 0 ]; // 假定最小值是第一列
var minIndex = 0;
// 求得最小值和最小值索引
for ( var i = 0; i < arr.length; i++ ) {
if ( min > arr[i] ) {
min = arr[ i ];
minIndex = i;
}
}
// 设置位置
$(this).css({
top: min + space,
left: minIndex * ( itemWidth + space )
})
// 更新数组
arr[ minIndex ] = $(this).height() + min + space;
}
})
// 求最大列
var maxHeight = Math.max.apply( null, arr );
$box.height( maxHeight );
})
$.fn.waterFall = function() {
// 1. 获取父元素和子元素, 以及他们的宽高
var $box = $(this);
var $items = $box.children();
var boxWidth = $box.width(); // 获取父元素的宽度
var itemWidth = $items.width(); // 获取子元素的宽度
var columns = 5; // 一行排 5 个元素
// 2. 计算间隔
var space = (boxWidth - itemWidth * columns) / (columns - 1); // 10
console.log( space );
// 3. 遍历排放子元素
var arr = [ 0, 0, 0, 0, 0 ]; // 初始化数组
$items.each(function( index, element ) {
// 找最小列高度 和 最小列索引
var min = arr[ 0 ]; // 假定最小值是第一列
var minIndex = 0;
// 求得最小值和最小值索引
for ( var i = 0; i < arr.length; i++ ) {
if ( min > arr[i] ) {
// 更新最小值
min = arr[ i ];
minIndex = i;
}
}
// top: 最小值 + 间隙
// left: 最小值索引 * ( 元素宽度 + 间隙 )
// 设置位置
$(this).css({
top: min + space,
left: minIndex * ( itemWidth + space )
})
// 更新数组
arr[ minIndex ] = $(this).height() + min + space;
})
// 求最大列
var maxHeight = Math.max.apply( null, arr );
$box.height( maxHeight );
};
需求分析:
1. 页面刚开始,没有任何一张图片。因此需要从通过ajax获取图片
2. 使用模版引擎将获取到的数据渲染到页面
3. 因为图片路径是从服务端获取的,加载需要时间, 渲染时需要设置宽高
4. 点击加载更多, 请求下一页数据, 注意: 加载时,显示"正在加载中...",并且要求不能重复发送ajax请求
5. 给window注册scroll事件,当触底时,需要动态的加载图片。(规定: 最后一张图片开始显示在屏幕中时, 加载图片)
6. 当服务端返回图片数量为0时,提示用户没有更多数据。
接口文档
//接口说明:瀑布流分页数据
//接口地址:data.php
//请求方式:get
//接口参数:page 当前是第几页 pageSize 当前页需要显示多少条
//返回类型 json
//返回数据:
{
page: 2,
items: [
{path: "./images/1.jpg",text:'', height: 280, width: 232},
{path: "./images/2.jpg",text:'', height: 164, width: 232},
...
]
}
page 下一页的页码
items 返回当前页的数据
path 图片地址
text 文字
height 图片高度
width 图片宽度
1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
协议相同
域名相同
端口相同
举例来说,这个网址http://www.example.com/dir/page.html
协议是http://
,
域名是www.example.com
,端口是80
(默认端口可以省略)。它的同源情况如下。
http://www.example.com/dir2/other.html:同源
file:///F:/phpStudy/WWW/day01/04-demo/04.html 不同源(协议不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。
1. Cookie、LocalStorage 和 IndexDB 无法读取。
2. DOM 无法获得。
3. AJAX 请求在浏览器端有跨域限制
虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域 。
【演示跨域问题.html】
JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。
原理:服务端返回一个定义好的js函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合
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>
php文件
header("content-type:text/html;charset=utf-8");
echo "alert(1111)";
html文件
<script src="http://www.api.com/testjs.php"></script>
原理:其实src的路径是什么文件不重要,无论引入js文件还是php文件,最后返回给浏览器的都是字符串,因此我们script标签是可以引入一个php文件的。
php文件
header("content-type:text/html;charset=utf-8");
echo "var a = 118;";
html文件
<script src="http://www.api.com/testjs.php"></script>
<script>
//a打印出来了118
console.log(a);
</script>
我们现在做到了一件事情,从不同源的php文件中获取到了数据
缺点:获取数据的script标签必须写在使用的script标签的前面,必须保证先有数据才能对数据进行渲染。
php代码
header("content-type:text/html;charset=utf-8");
$arr = array(
"name"=>"zs",
"age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo "func($result)";
js代码
<script>
function func(data) {
console.log(data);
}
</script>
<script src="http://www.api.com/testjs.php"></script>
缺点:后端必须知道前端声明的方法的名字,后端才能调用。
php代码
header("content-type:text/html;charset=utf-8");
$arr = array(
"name"=>"zs",
"age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo $_GET['callback']."($result)";
javascript代码
function fun(data) {
console.log(data);
}
var button = document.querySelector("button");
button.onclick = function () {
var script = document.createElement("script");
script.src = "http://www.api.com/testjs.php?callback=fun";
document.body.appendChild(script);
}
jsonp原理大家需要知道,但不用太过于去纠结这个原理,因为jquery已经帮我们封装好了,我们使用起来非常的方便。
//使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
$.ajax({
type:"get",
url:"http://www.Jepson.com/testjs.php",
dataType:"jsonp",
data:{
uname:"Jepson",
upass:"123456"
},
success:function (info) {
console.log(info);
}
});
【案例:查询天气.html】
【案例:省市区三级联动.html】
XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。
老版本的XMLHttpRequest的缺点:
1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
2. 传输数据时,没有进度信息,只能提示完成与否。
3. 受到了"同源策略"的限制
新版本的功能:
1. 可以设置timeout超时时间
2. 可以使用formData对象管理表单数据
3. 允许请求不同域名下的数据(跨域)
4. 支持上传二进制文件
5. 可以获取数据传输的进度信息
注意:我们现在使用new XMLHttpRequest创建的对象就是2.0对象了,我们之前学的是1.0的语法,现在学习一些2.0的新特性即可。
xhr.timeout = 3000;//设置超时时间
xhr.ontimeout = function(){
alert("请求超时");
}
formData对象类似于jquery的serialize方法,用于管理表单数据
使用特点:
1. 实例化一个formData对象, new formData(form); form就是表单元素
2. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
3. formData有一个append方法,可以添加参数。formData.append("id", "1111");
4. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。
代码示例:
//1. 使用formData必须发送post请求
xhr.open("post", "02-formData.php");
//2. 获取表单元素
var form = document.querySelector("#myForm");
//3. 创建form对象,可以直接作为send的参数。
var formData = new FormData(form);
//4. formData可以使用append方法添加参数
formData.append("id", "1111");
//5. 发送,不需要指定请求头,浏览器会自动选择合适的请求头
xhr.send(formData);
以前,文件上传需要借助表单进行上传,但是表单上传是同步的,也就是说文件上传时,页面需要提交和刷新,用户体验不友好,xhr2.0中的formData对象支持文件的异步上传。
var formData = new FormData();
//获取上传的文件,传递到后端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);
xhr2.0还支持获取上传文件的进度信息,因此我们可以根据进度信息可以实时的显示文件的上传进度。
1. 需要注册 xhr.upload.onprogress = function(e){} 事件,用于监听文件上传的进度.注意:需要在send之前注册。
2. 上传的进度信息会存储事件对象e中
3. e.loaded表示已上传的大小 e.total表示整个文件的大小
代码参考:
xhr.upload.onprogress = function (e) {
inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}
xhr.send(formData);
如果上传文件超过8M,php会报错,需要进行设置,允许php上传大文件。
新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称CORS)。
跨域资源共享(CORS)的前提
服务器允许跨域的代码:
//允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");
//允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");
浏览器发送跨域请求
服务器端收到一个跨域请求后,在响应头中添加Access-Control-Allow-Origin Header资源权限配置。发送响应
浏览器收到响应后,查看是否设置了header(‘Access-Control-Allow-Origin:请求源域名或者*‘);
如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。
结论:
【案例:图灵机器人】
标签:形参 不发送 响应 语言 根据 上传 children 这一 服务端
原文地址:https://www.cnblogs.com/f2ehe/p/12309152.html