跨域

实现跨域

页面中有几个可以允许跨域资源请求的标签,分别为a链接的herf、img的src、link的src跟script中的src

  1. 浏览器的同源限制。同源要域名、协议、端口都相同,如果是协议跟端口照成的不同源,前端是无法解决的
  2. 跨域并不是请求发不出去,请求可以发出去吗,服务器端能够接受到请求并返回数据,只是返回回来的时候被浏览器拦截了
  3. 所有的跨域必须要经过信息提供方的允许,如果未经允许被激活是浏览器的同源策略出现了问题

实现跨域的方式

服务端对响应头经行设置

在node中的的设置如下

1
2
3
4
app.all('*',function(req,res,next){
res.header('Access-Control-Allow-Origin','*');
next();
});

通过jsonp的方式

jsonp的实现原理如下

​ 利用了script标签的天然跨域特性,在发送请求的时候传递了一个函数给后台,后台最后以参数调用的方式返回数据,前端在另外的script标签内创建相同的函数,来接收后台返回过来的参数

​ jsonp实现跨域请求和Ajax请求的本质不一样,jsonp是通过script来发送跨域请求的请求方式是GET请求,但是Ajax是通过XMLHttpRequest实现请求的,并可以设置请求的方式

原生的请求过程

​ 须要手动创建script标签,然后设置src属性,拼接地址和一个callback(函数名称)。发起请求后,通过在另外一个script标签中设声明一个函数,名称与请求的函数名称相同,然后以形参来接收后端传过来的数据

思考误区: 既然script标签能够解决跨域问题获取数据,那么为什么后端不能直接给前端返回数据,而是一个所谓的调用?

​ script标签确实能够解决跨域并且获取数据,但是在前端并没有办法接收返回的数据。如果返回的是一个调用,那么只需要在另外一对script标签中,声明一个同名的函数体进行接收就可以了,后续的处理也是在函数内部经行的,也就是整个过程没有异步对象参与。

json_web.html

1
2
3
4
5
6
7
8
<script>
function callback (data) {
console.log(data)
}
</script>

<script src="http://127.0.0.1:8877/jsonp?cb=callback1"></script>
// jsonp就是前端利用src不存在同源限制 向服务器发送请求 服务器返回是一个函数的调用 同时传递一个参数

jsonp_server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
const express = require('express')
const app = express()
app.get('/jsonp', (req, res) => {
// 获取前端传递过来的回调函数名字
var fn = req.query.cb
// jsonp接口返回的是一个函数的调用
var obj = {name: 'zhangsan', age: 18}
// res.send(`callback(99999)`)
res.send(`${fn}(${JSON.stringify(obj)})`)
})
app.listen(8877, () =>{
console.log(`http://127.0.0.1:8877 启动了`)
})

jsonp为什么只能发送get请求

​ 因为发起请求的方式是script标签,而不是异步对象,所以选择不了请求方式,标签默认就是get请求

Ajax中的jsonp

![img](file:///D:/Hexo/blog/source/_posts/%E8%B7%A8%E5%9F%9F/ajaxkuyu.jpg?lastModify=1554291958)ajaxkuyu

通过cors的方式

cors的中文意思是跨域资源共享,须要在服务器端经行cors配置

  • cors发送的是正真的Ajax请求
  • cors支持Ajax跨域,如果要启用CORS跨域资源共享,关键在于服务器,只要服务器支持CORS跨域资源共享,则浏览器肯定能够正常访问这种CORS接口;而且用户在发送Ajax的时候,就向发送普通Ajax一样
  • 对node来说,如果想要开启CORS跨域通信,只需要安装cors模块即可

在node.js中入如果想要调用核心API须要通过require来调用

文件操作

通过require来node.js的核心API’ fs ‘文件系统

const fs = require('fs')

文件读取

fs核心模块中提供了一个fs.readFile方法,来读取指定目录下的文件

fs.readFile(path,[options],callback)

path 读取的文件的路径

options 表示要以什么样的编码格式来读取文件,默认编码格式为 null ,一般都会改为utf-8

callback 当文件读取完成,调用这个callback回调函数来处理读取的结果

第一个参数是错误对象err ,如果err为null就证明读取成功了没有出错

第二个参数是读取成功的结果data

错误优先回调函数

err.meeage 错误信息

1
2
3
4
fs.readFile('1.txt','utf-8',(err,data) => {
if(err) console.log('读取文件失败');//如果错误对象位真就代表读取文件失败
console.log(data);
})

文件的操作是一个异步的过程

fs提供了一个readFileSync方法来时文件读取能够同步

var fs = fs.readFileSync(path,options)

文件写入

fs.writeFile(‘path’,’data’,callback)

第一个参数也是一个要写入的路径,如果当前路径没有对应的文件,则自己创建在写入

第二个参数时要写入的数据

第三个参数为写入数据后的结果

1
2
3
4
5
fs.writeFile('1.txt','111',err => {

if(err) return console.log('写入文件失败')

})

每次写入都会覆盖,不会保留,所以要有文件追加

文件追加

fs.appendFile(‘path’,’data’,callback)

第二个参数为要追加的数据,其它的两个参数跟文件写入一致

1
2
3
4
5
fs.appendFile('1.txt','\n2222',err => {

if(err) return console.log('文件按追加失败')

} )

文件复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
方法1:
fs.readFile('1/txt','utf-8',(err,data) => {

if(err) return console.log('文件读取出差错了')

console.log(data)

fs.writeFile('2.txt',data,err => {

if(err) return console.log('文件写入失败')

console.log('文件按复制成功')

})

})
方法2:
fs.copyFile('.1txt','6.txt',err => {

if(err) return console.log('复制出错了')

console.log('文件复制成功了')

})

//第一个参数为被复制的文件名,第二个参数为要复制到的文件按名

读取文件信息

1
2
3
4
fs.stat('1.txt',(err,stats) => {
console.log(stats);//获取到文件的大小、创建实际按等信息
//获取到的文件大小的当为为字节B,一字节为8位(bit)
})

读取文件夹

1
2
3
4
5
6
fs.readdir('文件加路径',(err,files) => {

console.log(files)//获取到当前文件夹下的所有文件以一个数组的形式存放


})

​ 在对文件进行操作的是后都会涉及到路径的问题,如果不是在当前终端路径目录下执行,会导致报错,因为如果在在其他的位置的终端中执行会导致还没到文件所在路径的文件加就直接取在找文件,就会报错。如果使用绝对路径就 不会出现这样的情况

dirname //文件夹坐在文件的目录 和终端路径没有任何关系 filename //文件地址

路径操作

path也是node.js中的核心API,通过require来调用

const path = require(‘path’)

path中的join方法能够更好的将该路径片段进行拼接

path.join(‘/b’,’\a’)

1
2
3
4
5
6
7
const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname,'./3.txt'),'utf-8',function(err,data) {
if(err) return console.log('文件读取错误' + err.message);
console.log('读取内容成功内容为:' + data);

})

node.js

node.js 介绍

node.js是一个基于Chrome V8引擎的JavaScript运行环境

node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效

简单说就是node.js就是一个服务器端的JavaScript运行环境,可以让程序员,做后台服务器编程开发

node.js中包括 ECMAScript核心 全局成员 核心api

全局成员 console setinterval setTimeout

核心API模块 是node平台单独提供的一些api,node中没有DOM跟BOM

node 文件路径 就可以在node环境下执行js脚本
为了方便使用在终端在中输入cls可以清屏

REPL环境 用户可以在其中输入任意的合法的js代码,按node+enter就可以进入REPL环境

ECMAScript6常用语法

var存在变量提升的问题,用var定义变量,var变量没有块级作用域,容易照成变量污染 使用var定义的变量没有{}作用域

let声明变量没有变量提升 let声明的变量只能在其作用域类使用

const 定义常量,一旦设置不能够修改,也不存在变量提升问题只有在顶以后才能够使用,也有块级作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
for (var i = 0; i < 10; i++) {

}
console.log(i);
//输出结果为10因为是用var定义的没有块级作用域,变量i应该在{}中有效才对
for (let i = 0; i < 10: i++) {

}
console.log(i)
//会报错,因为let定义的变量只有在其所在的跨级作用域内才有效
const i = 10;
var i = 1;
//会报错因为const一旦设置就不能够修改,所以在循环语句中不能够用const来定义变量不然就会报错

解构复制语法

let{name} = user
所谓的解构赋值,就是把某个对象中的属性,当作变量给解放出来,这样在后面就可以当作变量直接使用了

箭头函数

(形参列表) => {

​ 函数代码

}
箭头函数的本质就是一个匿名函数,在箭头函数中,this永远和箭头函数外部的this一致

如果想要给箭头函数赋予名字,可以定义一个变量,将箭头函数赋值给变量

箭头函数的变体

  1. 如果左侧只有一个参数小括号可以省略

    1
    2
    3
    4
     var str = x => {
    var i = 10;
    console.log(i);
    }

  2. 如果右侧只有一行代码{}可以省略,会默认执行return所以return必须要去掉

    1
    var add = (x,y) => console.log(x + y);

  3. 如果左侧只有一个参数,并且右侧只有一行代码,()跟{}都可以省略,return也必须要去掉

    1
    var add = x => console.log(x + 10);

ES6

  1. 字符串拓展 startWidth和endWidth
    var str = ‘adfdasfg’
    startWidth判断是否以某一段字符开始 返回true或者false
    endWidth判断是否以某一段字符结束 返回true或者false

  2. 字符填充padStart和padEnd
    str.padStart(29,’cd’)
    第一个参数是填充之后字符串的总长度
    第二个参数是要填充的字符

  3. 模板字符串

  4. 函数拓展,参数默认值

    function fn(a) {
    var a = a || 10
    return a
    }
    function fn(a =10) {

    }
    fn()

  5. 展开运算符
    合并数组、合并对象
    var arr1 = [11,22,33]
    var arr2 = [33,44,55]
    var arr3 = [66,88,…arr1,..arr2]
    var arr = [11,22,11,22,44,55,44]
    var ss = new Set(arr)
    Set提供一个构造函数,唯一的
    Array.from(ss) 将类似于数组的东西转换为数组

#Typora For Markdown 语法

[TOC]

###数学表达式

要启用这个功能,首先到Preference->Editor中启用。然后使用$符号包裹Tex命令,例如:$lim_{x \to \infty} \ exp(-x)=0$将产生如下的数学表达式:

$\lim_{x \to \infty} \exp(-x)=0$

###下标

下标使用~包裹,例如:H~2~O将产生H~2~O, 即水的分子式。

###上标

上标使用^包裹,例如:y^2^=4将产生表达式y^2^ = 4

###插入表情:happy:

使用:happy:输入表情:happy:,使用:sad:输入表情:sad:,使用:cry:输入表情:cry:等。以此类推!

下划线

用HTML的语法<u>Underline</u>将产生下划线Underline.

删除线

GFM添加了删除文本的语法,这是标准的Markdown语法木有的。使用~~包裹的文本将会具有删除的样式,例如~删除文本~将产生删除文本的样式。

代码

  • 使用`包裹的内容将会以代码样式显示,例如
1
使用`printf()`

则会产生printf()样式。

  • 输入`

    1
    2

    *

    1
    2
    3
    4
    public Class HelloWorld{
    System.out.println("Hello World!");
    }

    1
    2
    3
    4
    5
    6
    7

    将会产生

    ~~~java
    public Class HelloWorld{
    System.out.println("Hello World!");
    }

    强调

    使用两个*号或者两个_包裹的内容将会被强调。例如

    1
    2
    **使用两个*号强调内容**
    __使用两个下划线强调内容__

    将会输出

    使用两个*号强调内容
    使用两个下划线强调内容
    Typroa 推荐使用两个*号。

    斜体

    在标准的Markdown语法中,*和_包裹的内容会是斜体显示,但是GFM下划线一般用来分隔人名和代码变量名,因此我们推荐是用星号来包裹斜体内容。如果要显示星号,则使用转义:

    1
    \*

    插入图片

    我们可以通过拖拉的方式,将本地文件夹中的图片或者网络上的图片插入。

    drag and drop image

插入URL连接

使用尖括号包裹的url将产生一个连接,例如:<www.baidu.com>将产生连接:<www.baidu.com>.

如果是标准的url,则会自动产生连接,例如:www.google.com

目录列表Table of Contents(TOC)

输入[toc]然后回车,将会产生一个目录,这个目录抽取了文章的所有标题,自动更新内容。

水平分割线

使用***或者---,然后回车,来产生水平分割线。


标注

我们可以对某一个词语进行标注。例如

1
2
某些人用过了才知道[^注释]
[^注释]:Somebody that I used to know.

将产生:

某些人用过了才知道[^注释]
[^注释]: Somebody that I used to know.

把鼠标放在注释上,将会有提示内容。

表格

1
2
3
4
5
|姓名|性别|毕业学校|工资|
|:---|:---:|:---:|---:|
|杨洋|男|重庆交通大学|3200|
|峰哥|男|贵州大学|5000|
|坑货|女|北京大学|2000|

将产生:

姓名 性别 毕业学校 工资
杨洋 重庆交通大学 3200
峰哥 贵州大学 5000
坑货 北京大学 2000

其中代码的第二行指定对齐的方式,第一个是左对齐,第二个和第三个是居中,最后一个是右对齐。

数学表达式块

输入两个美元符号,然后回车,就可以输入数学表达式块了。例如:

1
$$\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\\frac{\partial X}{\partial u} &  \frac{\partial Y}{\partial u} & 0 \\\frac{\partial X}{\partial v} &  \frac{\partial Y}{\partial v} & 0 \\\end{vmatrix}$$

将会产生:

$$\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\end{vmatrix}$$

任务列表

使用如下的代码创建任务列表,在[]中输入x表示完成,也可以通过点击选择完成或者没完成。

1
2
3
4
- [ ] 吃饭
- [ ] 逛街
- [ ] 看电影
- [ ] 约泡
  • [x] 吃饭

  • [x] 逛街

  • [x] 看电影

  • 约泡

列表

输入+, -, *,创建无序的列表,使用任意数字开头,创建有序列表,例如:

1
2
3
4
**无序的列表**
* tfboys
* 杨洋
* 我爱你

无序的列表

  • tfboys
  • 杨洋
  • 我爱你
1
2
3
4
**有序的列表**
1. 苹果
6. 香蕉
10. 我都不喜欢

有序的列表

  1. 苹果
  2. 香蕉
  3. 我都不喜欢

块引用

使用>来插入块引用。例如:

1
>这是一个块引用!

将产生:

这是一个块引用!

标题

使用#表示一级标题,##表示二级标题,以此类推,有6个标题。

JavaScript

函数中的this永远指向它的调用者

JavaScript中的面向对象

在JavaScript中的面向对象的设计思想是

  • 创建构造函数
  • 根据构造函数创建实例对象(通过构造函数new一个对象)
  • 通过构造函数创建的实例对象实现自己的行为(函数)

面向对象的抽象程度比函数要高,因为一个构造函数中既包含数据,又包括操作数据的方法

创建对象

  1. 可以通过nwe Object()的方式来创建:

    1
    2
    3
    4
    5
    6
    var Person = new Object() 
    Person.name = 'jack';
    Person.age = '18';
    Person.sayName = function () {
    console.log(this.name)
    }
  2. 每次通过new Object()的方法来完成比较复杂,所以可以通过它的简写形式字面量来创建

    1
    2
    3
    4
    5
    6
    7
    var Person = {
    name : 'jack',
    age : '18',
    sayName : function () {
    console.log(this.name);
    }
    }

如果想要生成2个Person实例对象可以通过工厂函数来实现函数重复的问题

1
2
3
4
5
6
7
8
9
10
11
12
function createPerson (name,age) {
return {
name : 'name',
age : 'age',
sayName : function () {
console.log(this.name)
}
}
}
//然后调用函数生成实例对象
var p1 = createPerson(jack,18);
var p2 = createPerson(nick,20);

通过工厂函数解决了创建多个对象的冗余问题

构造函数

1
2
3
4
5
6
7
8
9
function Person(name,age) {
this.name = 'name';
this.age = 'age';
this.sayName = function () {
console.log(name);
}
}
var p1 = new Person(jack,18);
var p2 = new Person(nick,20);

构造函数通过this指向实例对象

构造函数跟实例对象的关系,在实例对象都有一个为_ proto _的属性,在 _ proto _属性中有一个constructor属性指向创建该实例的构造函数。

构造函数带来的好处就是创建对象更加方便了,但由于如果创建多个实例对象的时候会出现数据的重复使用,这样会浪费内存,为了解决这个问题,可以把须要共享的函数定义到构造函数外部,在构造函数中直接调用就可以了,但是这样会造成全局变量命名的冲突的问题。

这个问题可以根据原型(prototype)来解决,在每一个构造函数中都有一个prototype属性,指向

什么是原型

​ 在JavaScript中当我们创建一个函数的时候就会在内存中自当的生成一个对象,并且每个函数都有一个prototype属性指向这个自动生成的对象即prototype的值为这个对象。这个对象就是函数的原型对象。在原型对象中有一个属性constructor指向这个函数,即constructor属性的值为创建的函数。

CSS3

CSS3

选择器

属性选择器

属性选择器:属性是相对于标签而言。所谓属性选择器就是根据指定名称的属性的值来查找元素

  1. E[attr]:查找指定的拥有attr属性的E标签。

  2. E[attr=value]:查找拥有指定的Attr属性并且属性值为value的E标签。

  3. E[attr*=value]:查找拥有指定的attr属性并且属性值中包含(可以在任意位置)value的E标签。

  4. E[attr^=value]:查找拥有指定的attr属性并且属性值以value开头的E标签。

  5. E[attr$=value]:查找拥有指定的attr属性并且属性值以value开结束的E标签。

兄弟选择器

兄弟伪类:

+: 获取当前元素的相邻的满足条件的元素

~: 获取当前元素后的满足条件的所有元素

伪类选择器

相当于父元素的伪类

E:first-child:查找E元素的父级元素中的第一个E元素。在查找时并不会限制查找元素的类型

E:last-child: 查找E元素的父级元素的最后一个指定类型的元素

E:nth-child(n) : 查找E元素的的父元素的第n个元素

E:nth-last-of(n):查找E元素的的父元素的第n个元素

E:target : 可以以锚点为目标元素的样式,当目标元素被触发为当前锚链接目标时,调用此伪类样式

伪元素选择

重点:E::before、E::after

  1. 是一个行内元素,须要转换成块:display:block; fload;** position:

  2. 必须添加content,哪怕不设置内容,也须要content:””,不然样式不会显示出来

  3. E::before :定义在一个元素的内容之前插入content属性定义的内容与样式

  4. E::after : 定义在一个元素的内容之后插入content属性定义的内容与样式

  • E::first-letter 文本第一字母或字
  • E::first-line 文本第一行
  • E::selection 可改变选中文本的样式

线性渐变

添加渐变:渐变不是一个单一的事件,它产生的是图像,所以须要background

  1. linear-gradient线性渐变指延着某条直线朝一个方向产生渐变的效果

    语法:linear-gradient(方向,开始颜色 位置,颜色2 位置,颜色3 位置…);

    • to left:设置渐变为从右到左。相当于: 270deg;
    • to right:设置渐变从左到右。相当于: 90deg;
    • to top:设置渐变从下到上。相当于: 0deg;
    • to bottom:设置渐变从上到下。相当于: 180deg。这是默认值,等同于留空不写。也可以直接指定度数,如45deg
  2. radial-gradient 径向渐变指从一个中心点沿着四周产生渐变效果

    语法:radial-gradient(形状,大小 坐标, 颜色1,颜色2…)

背景样式

设置背景平铺

round: 会将图片经行缩放之后在平铺

space:图片不会缩放平铺,只是会在图片之间产生相同的间距值

设置在滚动容器的背景行为:跟随滚动/固定

fixed: 背景图片的位置固定不变

scroll: 当滚动容器的时候,背景图片也会跟随滚动

local和scroll的区别:前提是当前滚动容器的内容

local:背景图片会跟随内容一起滚动

scroll: 背景图片不会跟随内容一起滚动

background-size属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
div{
width: 300px;
height: 500px;
border: 1px solid red;
/*添加背景*/
background-image: url("../images/bg-img.jpg");
/*background-image: url("../images/share1.png");*/
background-repeat: no-repeat;
/*设置背景图片的大小 宽度/高度 宽度/auto(保持比例自动缩放)
建议:在使用这个属性之前需确定宽高比与容器的宽高比是否一致,否则会造成图片失真变形*/
/*background-size: 300px 500px;*/
/*background-size: 300px;*/
/*设置百分比,是参照父容器可放置内容区域的百分比*/
/*background-size: 50% 50%;*/
/*设置contain:按比例调整图片大小,使用图片宽高自适应整个元素的背景区域,使图片全部包含在容器内
1.图片大于容器:有可能造成容器的空白区域,将图片缩小
2.图片小于容器:有可能造成容器的空白区域,将图片放大*/
/*background-size: contain;*/

/*cover:与contain刚好相反,背景图片会按比例缩放自 适应整个背景区域,如果背景区域不足以包含所有背景图片,图片内容会溢出
1.图片大于容器:等比例缩小,会填满整个背景区域,有可能造成图片的某些区域不可见
2.图片小于容器:等比例放大,填满整个背景区域,图片有可能造成某个方向上内容的溢出*/
background-size: cover;
}

background-origin

  1. 作用:background-orgin 属性规定backgrund-positon属性相对于什么位置来定位。默认值是left top 左上角
  2. 语法: background-orgin: padding-box|border-box|content-box
  3. 属性值说明:
    • border-box:从border的位置开始填充背景,会与border重叠
    • padding-box:从padding的位置开始填充背景,会与padding重叠
    • content-box:从内容的位置开始填充背景

background-clip

  1. 作用:设置内容的裁切,设置的是裁切控制的是显示
  2. 属性说明
    • border-box:显示border及以内的内容
    • padding-box:显示padding及以内的内容
    • content-box:显示content及以内的内容

过渡

添加过渡效果:过渡效果执行完毕后,默认会还原到原始状态

  1. transition-property:添加过渡效果的属性名称
  2. transition-duration:渡过效果耗时以秒作为当为
  3. transition-timing-function:设置时间函数–控制运动的速度
  4. transition-delay:过渡效果的延迟
  5. 简写:transition:属性名称 过渡时间 时间函数 延迟

transform

使用transform实现元素的移动,移动是参照元素的左上角,执行完毕后会回复到原始状态。

如果只有一个参数就代表x方向

如果有两个参数就代表x/y方向

缩放:scale 实现缩放 1指不缩放, >1放大 <1缩小 参照元素的几何中心

如果只有一个参数就代表x和y方向都等比的缩放,如果有2个参数就分别向各自的方向缩进

旋转:rotate

斜切:skew

动画

添加动画效果

  1. animation-name: 指定动画名称

  2. animation-duration: 设置动画总耗时

  3. animation-interation-count:设置动画的播放次数,默认为1,可以指定具体的数值,也可以指定infinite(无限次数)

  4. animation-direction:alternate 设置交替动画

  5. animation-delay:设置动画的延迟

  6. 设置动画结束时的状态:默认情况下动画结束后会回到原始状态

    • animation-fill-mode:
  • forwards:会保留动画结束时的状态,在有延迟的情况下并不会立即会到原始状态
  • backwards:不会保留动画结束时的状态,在添加了动画延迟的情况下,动画结束后会回到初始状态
  • both:会保留动画结束时的状态,在有延迟的状态下也会立刻进入动画的初始状态
  1. animation-timing-function:动画的时间函数

  2. animation-play-state:设置动画的播放状体 paused:暂停 running:播放

多列布局

常用属性

  1. column-count:属性设置列的具体个数
  2. column-width:属性控制列的宽度
  3. column-gap:两列之间的缝隙间隔
  4. column-rule:规定列之间的宽度、样式和颜色
  5. column-span:规定元素应横跨多少列

伸缩布局

HTML5

HTML5

新增加的标签

​ 为了更好的处理今天的互联网,HTML5添加了许多新的元素及功能,比如:图形绘制,多媒体内容,更好的页面结构,更好的形式处理,和几个api拖放元素,定位,包括网页 ,应用程序缓存,存储网络工作等

canvas

标签 描述
标签定义图形,比如图表和其他图像。该标签基于JavaScript的绘图api

多媒体

标签 描述
定义音频
定义视频
定义多媒体资源
定义嵌入内容,比如插件
为诸如

​ 在h5中增加了语义标签,对浏览器的搜索引擎更加友好,让网页的内容更加容易被被收索引擎抓取,网页的推广会更加容易

标签 描述
定义页面的侧边栏内容
定义页面内容之外的内容。
允许您设置一段文本,使其脱离其父元素的文本方向设置。
定义命令按钮,比如单选按钮、复选框或按钮
用于描述文档或文档某个部分的细节
定义对话框,比如提示框
标签包含 details 元素的标题
规定独立的流内容(图像、图表、照片、代码等等)。
定义
元素的标题
定义 section 或 document 的页脚。
定义了文档的头部区域
定义带有记号的文本。
定义度量衡。仅用于已知最大和最小值的度量。
定义运行中的进度(进程)。
定义任何类型的任务的进度。
定义 ruby 注释(中文注音或字符)。
定义字符(中文注音或字符)的解释或发音。
在 ruby 注释中使用,定义不支持 ruby 元素的浏览器所显示的内容。
定义文档中的节(section、区段)。
定义日期或时间。
规定在文本中的何处适合添加换行符。
1
2
3
4
5
6
7
8
<body>
<header>定义了文档的头部区域</header>
<div>
<article>定义页面的侧边栏内容</article>
<aside>定义页面内容之外的内容</aside>
</div>
<footer>定义 section 或 document 的页脚</footer>
</body>

在默认情况下IE8及一下的版本不支持HTML5,引入html5shiv.min.js这个文件就可以解决兼容性的问题

新增的type属性

  1. email: 输入email的格式
  2. tel : 手机号码
  3. url: 只能输入url格式
  4. number: 只能输入数字
  5. search: 搜索框
  6. range: 范围,可以经行拖动,通过value值进行取值
  7. color: 拾色器,通过value经行取值
  8. time: 时间
  9. data: 日期 不是绝对的
  10. datatime: 世家日期
  11. month: 月份
  12. week: 星期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<form action="">
用户名:<input type="text" name="userName"> <br>
密码:<input type="password" name="userPwd"> <br>
<!--email提供了默认的电子邮箱的完整验证:要求必须包含@符号,同时必须包含服务器名称,如果不能满足验证,则会阻止当前的数据提交-->
邮箱:<input type="email"> <br>
<!--tel它并不是来实现验证。它的本质目的是为了能够在移动端打开数字键盘。意味着数字键盘限制了用户只能输入数字。 如何查看效果:qq发送文件>>手机端使用qq来接收>>使用手机浏览器查看-->
电话:<input type="tel"> <br>
<!--验证只能输入合法的网址:必须包含http://-->
网址:<input type="url"> <br>
<!--number:只能输入数字(包含小数点),不能输入其它的字符
max:最大值
min:最小值
value:默认值-->
数量:<input type="number" value="60" max="100" min="0"> <br>
<!--search:可以提供更人性化的输入体验-->
请输入商品名称:<input type="search"> <br>
<!--range:范围-->
范围:<input type="range" max="100" min="0" value="50"> <br>
颜色:<input type="color"> <br>
<!--日期时间相关-->
<!--time:时间:时分秒-->
时间:<input type="time"> <br>
<!--date:日期:年月日-->
日期:<input type="date"> <br>
<!--datetime:大多数浏览器不能支持datetime.用于屏幕阅读器-->
日期时间:<input type="datetime"><br>
<!--datetime-local:日期和时间-->
日期时间:<input type="datetime-local"> <br>
月份:<input type="month"> <br>
星期:<input type="week">
<!--提交-->
<input type="submit">
</form>

表单新增的属性

  • placeholder: 占位符
  • autofocus: 自动获取焦点
  • autocomplete : 自动完成 on打开 off关闭 当前添加autocomplete的属性必须要有name属性
  • required: 验证条件必须又输入,如果没有输入会阻止当前数据的提交
  • pattern: 正则表达式 验证表单
  • multiple: 文件上传多选或者多个邮箱地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<form action="" id="myForm">
<!--placeholder:提示文本,提示占位-->
<!--autofocus:自动获取焦点-->
<!--autocomplete:自动完成:on:打开 off:关闭
1.必须成功提交过:提交过才会记录
2.当前添加autocomplete的元素必须有name属性-->
用户名:<input type="text" name="userName" placeholder="请输入用户名" autofocus autocomplete="on"> <br>
<!--tel并不会实现验证,仅仅是在移动端能够弹出数字键盘-->
<!--required:必须输入,如果没有输入则会阻止当前数据提交-->
<!--pattern:正则表达式验证
*:代表任意个
?:代表0个或1个
+:代表1个或多个-->
手机号:<input type="tel" name="userPhone" required pattern="^(\+86)?1\d{10}$"> <br>
<!--multiple:可以选择多个文件-->
文件:<input type="file" name="photo" multiple> <br>
<!--email:有默认验证 在email中,multiple允许输入多个邮箱地址,以逗号分隔-->
邮箱:<input type="email" name="email" multiple><br>

<!--提交:-->
<input type="submit"> <br>
</form>
<!--下面这个表单元素并没有包含在form中:默认情况下面表单元素的数据不会进行提交-->
<!--form:指定表单id,那么在将来指定id号的表单进行数据提交的时候,也会将当前表单元素的数据一起提交-->
地址:<input type="text" name="address" form="myForm">

在下拉菜单中不仅要可以选择,还要可以输入,通过datalist标签创建选择列表,通过list的id建立输入框与datalist的关联

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--不仅可以选择,还应该可以输入-->
<!--建立输入框与datalist的关联 list="datalist的id号"-->
专业:<input type="text" list="subjects"> <br>
<!--通过datalist创建选择列表-->
<datalist id="subjects">
<!--创建选项值:value:具体的值 label:提示信息,辅助值-->
<!--option可以是单标签也可以是双标签-->
<option value="英语" label="不会"/>
<option value="前端与移动开发" label="前景非常好"></option>
<option value="java" label="使用人数多"></option>
<option value="javascript" label="做特效"></option>
<option value="c" label="不知道"></option>
</datalist>

多媒体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!--embed:可以直接插入音频视频,本质是通过本机安装的音频视频播放软件来播放的。要求必须已经安装了这些软件  兼容性-->

<!--flash: 1.先学习flash,增加使用成本 2.iphone,ipd,不支持flash-->

<!--audio:音频-->
<!--
src:播放文件的路径
controls:音频播放器的控制器面板
autoplay:自动播放
loop:循环播放-->
<!--<audio src="../mp3/aa.mp3" controls></audio>-->

<!--video:视频-->
<!--
src:播放文件的路径
controls:音频播放器的控制器面板
autoplay:自动播放
loop:循环播放
poster:指定视频还没有完全下载完毕,或者用户没有点击播放前显示的封面。 默认显示当前视频文件的第一副图像
width:视频的宽度
height:视频的高度
-->
<!--注意事项:视频始终会保持原始的宽高比。意味着如果你同时设置宽高,并不是真正的将视频的画面大小设置为指定的大小,而只是将视频的占据区域设置为指定大小,除非你设置的宽高刚好就是原始的宽高比例。所以建议:在设置视频宽高的时候,一般只会设置宽度或者高度,让视频文件自动缩放-->
<!--<video src="../mp3/mp4.mp4" poster="../images/l1.jpg" controls height="600"></video>-->

<!--source:因为不同的浏览器所支持的视频格式不一样,为了保证用户能够看到视频,我们可以提供多个视频文件让浏览器自动选择-->
<!--<video src="../mp3/flv.flv" controls></video>-->
<video controls>
<!--视频源,可以有多个源-->
<source src="../mp3/flv.flv" type="video/flv">
<source src="../mp3/mp4.mp4" type="video/mp4">
</video>

HTML5中的API

FileReader的使用

FileReader: 读取文件内容

  1. readAsText() : 读取文本文件(可以使用Txt打开的文件),返回文本时字符串,默认编码为utf-8
  2. readAsBinaryString() :读取任意类型文件。返回二进制字符串。这个方法不是用来读取文件展示给用户看,而是用开读取文件。例如:读取文件类容,获取二进制数据,传递后台,后台接收数据之后在将数据存储。
  3. readAsDataURL(): 读取文件获取一串以data开头的字符串
  4. abort(): 中断读取

FileReader提供一个完整的时间模型,用来捕获读取文件时的状态

  • onabort : 读取文件中断片时触发
  • onerror : 读取文件错误时触发
  • onload : 文件读取成功完成时触发
  • onloadend : 读取完成时触发,无论读取成功还是失败都触发
  • onloadstart : 读取开始时触发
  • onprogress :读取文件过程中持续触发

拖拽接口的使用

​ 在HTML5中,如果想拖拽元素,就必须为元素添加draggable=’true’. 图片和超链接默认可以拖拽

  1. 用于被拖拽元素的事件
    • ondrag 应用于拖拽元素,整个托的过程都会持续调用
    • ondragstart 应用于拖拽元素,当拖拽开始时调用
    • ondragleave 应用于拖拽元素,当鼠标离开拖拽元素的时候调用
    • ondragend 应用于拖拽元素,当拖拽结束时调用
  2. 应用于目标元素的事件
    • ondragenter 应用于目标元素,当拖拽元素进入时调用
    • ondragover 应用于目标元素,当停留在目标元素上时调用
    • ondrop 应用于目标元素,当在鼠标元素上松开鼠标的时候调用 浏览器会默认阻止ondrop事件,必须在ondragover事件中阻止浏览器默认行为 e.preventDefalut();
    • ondragleave 应用于目标元素,当鼠标离开目标元素的时候调用

​ 为了能够让多个元素能够被拖拽,应该通过事件捕获来获取当前被拖拽的子元素,给document注册事件通过事件捕获来过去要拖拽的元素.通过dataTransfer来实现数据的存储与获取

​ * setData(format,data):

​ * format:数据的类型:text/html text/uri-list

​ * Data:数据:一般来说是字符串值

sessionStorge的使用

sessionStorge的使用:存储数据到本地。存储的容量5MB左右。

  1. 这个数据本质是存储在当前页面的内存中-意味着其他页面和浏览器无法获取到数据
  2. 它的生命周期为关闭当前页面,关闭页面,数据会自动清除
  • setItem(key,value) : 存储数据以键值对的方式存储

  • getItem(key) : 获取数据,通过指定名称的key获取对应的value的值

  • removeItem(key) : 删除数据,通过指定名称的key删除对应的value的值

  • clean() : 清空所有的存储内容

localStorage 的使用

localStorage的使用:

  1. 存储内容大概为20MB
  2. 不同浏览器不能共享数据。但在同一个浏览器的不同窗中可以共享数据
  3. 永久生效,它的数据存储在硬盘上,并不会随着浏览器或者页面的关闭而清除,如果想清除,必须要手动清除
  • setItem(key,value) : 存储数据以键值对的方式存储
  • getItem(key) : 获取数据,通过指定名称的key获取对应的value的值
  • removeItem(key) : 删除数据,通过指定名称的key删除对应的value的值
  • clean() : 清空所有的存储内容

Ajax学习第三天

跨域请求资源

同源:同源策略是一种安全策略要求域名以及端口完全相同

不是同源的则须要跨域请求资源

注意:跨域并不是请求发不出去,请求能发出去,服务器端能收到请求并正常返回结果,值时结果被浏览器拦截了

实现跨域的2种方法

  1. 服务器端设置CORS跨域

    1
    2
    3
    4
    5
    6
    7
    <?php
    // 设置跨域请求
    header("Access-Control-Allow-Origin:*"); // * 允许代表所有域来请求
    header("Access-Control-Allow-Origin:http://day09.com");

    echo file_get_contens("nav.json");
    ?>

  2. 通过jQuery中的jsonp实现跨域

    步骤1: 发送请求的时候设置dataType的类型
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $.ajax({
    type: "get",
    url: "http://day8.com/getnav.php",
    dataType: "jsonp",
    success: function(res) {
    var html = template("navTemp", {"items": res})
    document.querySelector("ul").innerHTML = html
    }
    })
    步骤2: 查看jsonp请求

    jsonp

    ​ 拿到了数据但是没有调用,所以渲染不成功

    步骤3:服务器端的配合
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    // 这就是客户端请求时传递过来的函数名称
    $callback = $_GET["callback"];
    // 读取数据
    $data = file_get_contens("nav.json");
    // 返回调用函数的形式,只不过要传递前端需要的数据
    echo $callback."('.$data.')"; // acb()
    ?>

jsonp 的实现过程

​ 如果要追究他的过程,那么要知道的是,这里发起的请求并不是由异步对象完成的,而是由jQuery动态创建的script标签,并且设置了地址和随机生成的回调函数的名称数据成功返回后,会把这个标签销毁,那么此时信息提供方返回的调用和数据将会在success函数中接收

​ 原生的请求过程

​ 须要手动创建script标签,然后设置src属性,拼接地址和一个callback= 函数名,发起请求后,通过在另外一个script标签中创建一个函数,名称与请求的函数名称相同,然后以形参作为最终的数据

客户端 服务器端
步骤1:请求发起,配置了dataType为jsonp,由jQuery自动的完成一个请求的发送,并创建一个随机的方法名称 步骤1:根据前端发起的get请求,获取到$callback,这里的 \$callback是jQuery发起请求自动生成的一个随机名称避免
步骤2:接收响应回来的数据,‘随机方法的名称(res)’ 步骤2:获取数据,读取数据$res
步骤3:在客户端中创建对应的函数声明取去接收服务器端返回的数据,那么就应该在当前的函数的内部完成最后的功能function 随机函数名称(result) {//这里就是最终接收到的数据} 步骤3:返回一个方法的调用,但是是以字符串的方式 >要把这个方法的调用给客户端 “$callback(\$res)” >如果不写成字符串,那么就会在当前文件

AJAX学习第二天

在jQuery中的Ajax

​ 首先要引用jquery-1.12.2.min.js文件

$.ajax({这里传入一个字面量对象}) 参数说明
url 接口地址
type 请求方式
timeout 请求超时,单位是毫秒
dataType 服务器返回的格式, json / xml / jsonp
data 发送请求的数据
beforeSend: fucntion() { …code } 请求发起前的调用
success: fucntion() { …code } 成功响应后的调用
error: fucntion() { …code } 错误响应时的调用,e参数为报错信息
complete: fucntion() { …code } 响应完成时的调用

​ 完整的jQuery调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$.ajax({
type: 'post',
url: './server/nav-json.php',
data: {}, //请求需要传递的参数
// 设置请求超时:单位为毫秒,如果服务器的响应时间超过指定的时候,请求失败
timeout: 3000,
dataType:'json', // 设置响应数据的格式 xml json text html script jsonp
// 发送请求之前的回调
beforeSend:function(){
// 在这个回调函数中,如果return false,那么本次请求会中止
// return false;
},
success: function() {
//请求成功之后的回调
},
// 请求失败之后的回调
error:function(e){
if(e.statusText == "timeout"){
alert("请求超时,请重试");
}
},
// 无论请求是成功还是失败都会执行的回调
complete:function(){
console.log('实现一些全局成员的释放,或者页面状态的重置....');
}
});

注册案例

案例要达到的效果

register

准备1:获取验证码的getCode.php文件
1
2
3
4
5
6
7
<?php
$arr = array('12345','23456','34567','45678');
/*生成一个随机索引 array_rand:可以生成指定的数组长度内的索引*/
$index = array_rand($arr);
sleep(2);
echo $arr[$index];
?>
准备2:数据的data.json文件
1
2
3
4
5
[
{"name":"jack","pass":"rose","mobile":"12345678901"},
{"name":"rose","pass":"123","mobile":"12345678902"},
{"name":"tom","pass":"123","mobile":"12345678909"},
]
准备3:验证用户名是否存在的validataUsername.php文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
if($_SERVER['REQUEST_METHOD'] == 'GET'){
/*1.读取文件*/
$dataStr = file_get_contents('data.json');
/*2.转换为数组,因为我们需要判断数组中的成员的name属性是否是指定的用户名--遍历*/
$dataArr = json_decode($dataStr);
/*3.遍历*/
for($i=0;$i<count($dataArr);$i++){
if($dataArr[$i] -> name == $_GET['name']){
$arr = array(
'code'=>0, //状态码
'msg'=>'用户名已存在' //状态信息
);
echo json_encode($arr);
return;
}
}
}
?>
准备4:收集用户数据,实现上传和写入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$name = $_POST['name'];
$pass = $_POST['pass'];
$mobile = $_POST['mobile'];
/*创建需要进行存储的当前用户注册对象*/
$obj = array(
'name' => $name,
'pass' => $pass,
"mobile" => $mobile
);
/*php无法直接将一个数据存储到文件,它需要先将数据写入到数组,再将数组写入到文件*/
$arr = file_get_contents('data.json'); //字符串
$dataArr = json_decode($arr); //将json格式字符串转换为php数组
/*向数组中添加数据*/
$dataArr[] = $obj;
/*将数据写入到文件,写入到文件的数据只能是字符串*/
$resultStr = json_encode($dataArr); //将数组转换为json格式字符串
file_put_contents('data.json',$resultStr);

echo json_encode(array('code'=>1,"msg"=>'注册成功'));
?>
准备5:在前端页面引入jQuery文件

​ 引入jQuery文件,创建开始任务的js标签

1
2
3
4
5
6
<script src="jquery-1.12.2.min.js" ></script>
<script>
// 1.0 获取验证码
// 2.0 完成验证操作
// 3.0 提交表单,进行上传操作
</script>

实现获取验证码

​ 步骤1: 为按钮添加单击事件

​ 步骤2:收集手机号,向服务器发送获取验证码的请求

​ 步骤3:接收验证码,给出响应的提示信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(".name").on("blur", function() {
var name = $(this).val();
$.ajax({
type: "get",
url: "./server/validataUsername.php",
data: {"name":name},
dataType: "json", // 接收到的就是一个js的对象,不然就是一个字符串
success: function(res) {
// console.log(res)
if(res && res.code == 0) {
$(".tips > p").text(res.msg).fadeIn().delay(2000).fadeOut()
}
}
})
})

实现注册

​ 步骤1:添加注册事件

​ 步骤2:收集用户数据

​ 步骤3:发起ajax请求

​ 步骤4:接收响应,给出提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$(".submit").on("click", function() {
if($(this).hasClass("disabled")) {
return;
}
// 通过表单序列化的方式来收集用户数据
var data = $("#ajaxForm").serialize();
$.ajax({
type: "post",
url: "./server/register.php",
data: data,
dataType: "json",
beforeSend: function() {
// 用户输入合法的验证
// 如果验证通过,开启节流阀,避免重复提交
$(".submit").addClass("disabled").val("正在注册中");
},
success: function(res) {
if(res && res.code == 1) {
$(".tips > p").text(res.msg).fadeIn().delay(2000).fadeOut()
}
},
error: function() {
$(".tips > p").text("注册失败").fadeIn().delay(2000).fadeOut()
}, // 不管成功还是失败都会执行
complete: function() {
$(".submit").removeClass("disabled").val("注册");
}
})
})

在php文件后添加一句

1
echo json_encode(array('code'=>1, 'msg'=>'注册成功'));
jquery的表单序列化方法
$(“#ajaxForm”).serialize();
可以将表单中所有name属性的表单元素的值收集,生成key=value&key=value
在ajax中,支持两种格式的参数(1,对象,2,参数格式字符串)

art-template模板引擎

模板引擎的2种语法

原生语法
  • 步骤1:引入文件

    1
    <script src="./js/template-native.js"></script>

  • 步骤2:创建模板数据

    1
    2
    3
    4
    5
    6
    7
    8
    <script type="text/template" id="navTemp">
    <li>
    <a href="#">
    <img src="<%= src %>" alt="">
    <p><%= text %></p>
    </a>
    </li>
    </script>

  • 步骤3:调用模板引擎

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    var obj = {
    "src": "./images/nav-1.png",
    "text": "京东超市"
    }
    // 调用函数 templete(模板id, 数据(对象)) 返回替换后的DOM结构
    var html = template(navTemp, obj);
    document.querySelector("ul").innerHTML = html;
    </script>

AJAX学习(第一天)

AJAX简要札记

1.0 关于ajax和异步

ajax是什么

​ Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术

​ 关键词: 异步,不需要页面跳转局部刷新

__本质: 基于http协议以异步的方式通过 XMLHttpRequest对象 向服务器进行通信__

__作用: 在页面不刷新的情况下,请求服务器,实现局部的渲染数据__

什么是异步

​ 异步的反义词就是同步,同步指在网页的一次请求中,如果不完成这次请求,就不会响应其他的任何操作,效率比较慢;

通过后台处理页面跳转
1
2
3
4
5
6
7
8
/*  
以往方式写出来的页面,是静态的,数据没有办法改变和刷新
使用php书写:
a, 所有要操作的文件后缀名改成php, 或者通过提交按钮和a链接跳转到php文件
b, 参数必须拼在a链接后面或者form表单内部
b, 书写符合php语法的代码,方法较多难以记忆
c, 在页面中来来回回的跳转, 发送的请求要等待完成之后才能做其他的操作
*/

old-request

前端的

register.html文件

1
2
3
4
5
6
7
<form action="./register.php" method="post">     
<span id="msg">aaa</span>
用户名:<input type="text" id="userName" name="username" >
昵称:<input type="text" name="nickname" >
密码: <input type="password" name="password" >
<input type="submit" value="注册">
</form>

后台处理的php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
header('content-type:text/html;charset=utf-8');
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//获取用户名
$name=$_POST['username'];
//判断数据库中是否已有这个用户名
$names=['jack','rose','tom','lili'];
//有则注册失败,否则成功
if(in_array($name,$names)){
$str = '这个名字太火了,换一个吧!';
echo $str;
header("refresh:10;url=register.html");
}else{
$str = '恭喜,名字可用!';
echo $str;
header("refresh:2;url=register.html");
}
}
?>
通过前端发送ajax请求

​ 异步就是在发起请求之后,不用理会这个过程,等请求结束了,自动返回回来数据,不用进行等待;

1
2
3
4
5
6
/*
a, 原先是html的文件还是html,不用修改文件类型
b, 发送请求不再仅仅依靠a链接或者表单元素
c, 不需要来回跳转页面,用户不需要进行等待
d, 返回的数据可以在局部进行刷新
*/

ajax

前端的register.html文件

1
2
3
4
5
6
7
8
9
10
<form>     
<span id="msg">aaa</span>
用户名:<input type="text" name="username" id="username">
昵称:<input type="text" name="nickname" >
密码: <input type="password" name="password" >
<input type="submit" value="注册">
</form>

<!-- 显示ajax请求返回回来的数据 -->
<div class="showmsg"></div>

前端基于http发送的一个异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
document.querySelector("#username").onblur = function(){
// 1.获取用户数据
var name = this.value;

// 2.1 创建异步对象
var xhr = new XMLHttpRequest();
// 2.2 请求行发送 open(请求方式,请求url+键值对的参数):
xhr.open("get","validate.php?username="+name);
// 2.3 get请求没有请求头
// 2.4 请求体:发送请求
xhr.send(null);

// 2.5 通过readystate发生改变的事件处理响应
xhr.onreadystatechange = function(){
// 2.6 判断请求是否结束后成功返回 判断服务器状态码是否为200
if(xhr.readyState == 4 && xhr.status == 200){
// 通过xhr对象的responseText接收返回的数据,写入盒子内
document.querySelector(".showmsg").innerHTML = xhr.responseText;;
}
}
};

处理后端的php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
header('content-type:text/html;charset=utf-8');
if($_SERVER['REQUEST_METHOD'] == 'GET'){
//获取用户名
$name=$_GET['username'];
//判断数据库中是否已有这个用户名
$names=['jack','rose','tom','lili'];
//有则注册失败,否则成功
if(in_array($name,$names)){
$str = '这个名字太火了,换一个吧!';
echo $str;
// header("refresh:10;url=register.html");
}else{
$str = '恭喜,名字可用!';
echo $str;
// header("refresh:2;url=register.html");
}
}
?>

前端的get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1.1 创建异步对象
var xhr = new XMLHttpRequest();
// 1.2 请求行发送 open(请求方式,请求url+键值对的参数):
xhr.open("get","validate.php?username="+name); // url地址 ? 键=值 & 键=值 & 键=值
// 1.3 get请求没有请求头
// 1.4 请求体:发送请求
xhr.send(null);

// 1.5 通过readystate发生改变的事件处理响应
xhr.onreadystatechange = function(){
// 1.6 判断请求是否结束后成功返回 判断服务器状态码是否为200
if(xhr.readyState == 4 && xhr.status == 200){
// 通过xhr对象的responseText接收返回的数据,写入盒子内
document.querySelector(".showmsg").innerHTML = xhr.responseText;
}
}

前端的post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1.1 创建异步对象
var xhr = new XMLHttpRequest();
// 1.2 设置请求行 open(请求方式,请求url)
// post请求不需要拼接参数
xhr.open("post","validate.php");
// 1.3 设置请求头:setRequestHeader()
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 1.4 设置请求体 send()
// post的参数在这个函数中设置(如果有参数)
xhr.send("username="+name);

// 1.5 通过readystate发生改变的事件处理响应
xhr.onreadystatechange = function(){
// 1.6 判断请求是否结束后成功返回 判断服务器状态码是否为200
if(xhr.readyState == 4 && xhr.status == 200){
// 通过xhr对象的responseText接收返回的数据,写入盒子内
document.querySelector(".showmsg").innerHTML = xhr.responseText;
}
}

关于get请求和post的请求区别是什么

1、GET没有请求主体,使用xhr.send(null)
2、GET可以通过在请求URL上添加请求参数
3、POST可以通过xhr.send(‘name=itcast&age=10’)
4、POST需要设置 Content-type:application/x-www-form-urlencoded


2.0 使用异步对象发送读取JSON文件

​ 在项目开发过程中,用的最多的方式就是json

json格式的数据和特点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"src":"./images/nav_1.png" ,
"text":"京东超市"
},
{
"src":"./images/nav_2.png" ,
"text":"全球购物"
},
{
"src":"./images/nav_3.png" ,
"text":"京东市场"
}
]
规则和特点
关于json的描述
1,一组花括号表示一个对象,一个对象通过键值对写入一堆相关数据
2,一组方括号表示一个数组,多组对象通过数组的方式装载
3,对象的所有属性都必须加上双引号,值没有undefined
4,文件后缀名为.json,json格式的数据内不允许写注释
操作json的方法
前端操作json的方式
JSON.parse(json字符串) 将json格式的字符串转换为数组或者对象
JSON.stringify(对象或者数组) 将字面量对象或者数组转换为json格式的字符串
php操作json的方式
json_decode(json字符串) 将json格式的字符串转换为php的数组或者对象
json_encode(关联数组) 将php的数组转换为json字符串

关于json的操作

​ 拿到数据之后,大部分情况下是一个装了很多数据的数组,里面是一个个对象

所以需要对数组进行循环遍历

通过for循环,拿到每一个对象,通过在循环中,拿到当前对象某个属性对应的值

data[i].src data[i]["src"]

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
xhr.onreadystatechange = function(){
if(xhr.status == 200 && xhr.readyState == 4){
var result = xhr.responseText;
// 通过操作json的方法获取到data数组
var data = JSON.parse(result);

var arr = [];
for(var i=0;i<data.length;i++){
var str = "<li>"
+ '<a href="#">'
+ '<img src="' + data[i].src + '" alt="">'
+ '<p>' + data[i].text + '</p>'
+ '</a>'
+ '</li>';
arr.push(str)
}
// 将生成的页面结构添加到dom元素中
document.querySelector("ul").innerHTML = arr.join("");
}
}

后端处理php文件的代码

1
2
3
<?php
echo file_get_contents("../data/nav.json");
?>

3.0 xml语法和文件操作

​ 以前比较频繁的数据传输方式就是xml的文件格式,它是html的一个扩展

xml文件格式的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<!-- 上面这一句必须是整个xml文档的第一句,否则格式错误 -->
<root>
<!-- 标签名称 以字母和下划线开头,不能有空格,不能包含特殊字符,区分大小写 -->
<items>
<!-- 说明下面的内容需要描述为数组 -->
<item>
<!-- 描述数组中的具体的成员值 -->
<src>./images/nav_1.png</src>
<text>京东超市</text>
</item>
<item>
<!-- 描述数组中的具体的成员值 -->
<src>./images/nav_2.png</src>
<text>全球购物</text>
</item>
<item>
<!-- 描述数组中的具体的成员值 -->
<src>./images/nav_3.png</src>
<text>京东市场123</text>
</item>
</items>
</root>
xml文件的规则和特点
关于xml数据格式的规则
1,文件后缀名必须得为.xml格式
2,必须得在头部声明那样一句话,相当于doctype声明
3,内容都以双标签包裹,可以嵌套和并列,不能交叉
4,标签名称以字母和下划线开头,叫什么,多长的名称无所谓

关于xml的操作

前端获取xml文件的内容

​ 在响应成功后,通过responseXML来接收当前的数据,会拿到一长串标签

​ 此时可以使用js中选择器,选择对应的标签 xhr.responseXML.querySelector(“标签名称”)

​ 如果获取到的是多个元素,则需要遍历,也是可以通过获取元素内的数据传递给其他标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
xhr.onreadystatechange = function(){
if(xhr.status == 200 && xhr.readyState == 4){
// responseText:接收普通字符串 responseXML:专门用来接收服务器返回的xml数据的
var result = xhr.responseXML;
// 将获取到的数据生成动态的页面结构
var items = result.querySelectorAll("item");

var arr = [];
for(var i=0;i<items.length;i++){
// 获取到标签内部的数据
var src = items[i].querySelector("src").innerHTML;
var text = items[i].querySelector("text").innerHTML;
var str = "<li>"
+ '<a href="#">'
+ '<img src="' + src + '" alt="">'
+ '<p>' + text + '</p>'
+ '</a>'
+ '</li>';
arr.push(str)
}
// 将生成的页面结构添加到dom元素中
document.querySelector("ul").innerHTML = arr.join("");
}
}

后端php文件处理xml文件的请求

1
2
3
4
5
6
7
<?php
// 默认返回数据的类型
// header("Content-Type:text/html;charset=utf-8");
// 如果需要返回数据为xml,那么标准的响应头的写法应该是
header("Content-Type:application/xml;charset=utf-8");
echo file_get_contents("../data/nav.xml");
?>

4.0 改进和封装工具

$$
封装的目的是为了方便更高效的使用,一次封装多次调用
$$

代码的封装

​ 关于代码的封装,重点在于要知道怎么使用,具体的封装过程等到了一定的开发经验再把玩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
var dilireba = {
// 将{"name":"jack","age":20} 的参数要转换为 ?name=jack&age=20
getpa:function(data){
if(data && typeof data == "object"){
var str = "?";
for(var key in data){
str = str + key + "=" + data[key] + "&";
}
str = str.substr(0,str.length-1);
}
return str;
},
ajax:function(option){
// 接收用户参数进行相应处理
var type = option.type || 'get';
// location.href 可以获取当前文件的路径
var url = option.url || location.href;
// 接收参数:在js中最方便收集的数据类型为对象,所以我们就规定传递的参数必须是对象
var data = this.getpa(option.data) || "";
// 响应成功之后的回调函数 => 这个函数一般就是处理字符拼接,标签渲染的函数
var success = option.success;

// 创建异步对象
var xhr = new XMLHttpRequest();
// 请求行 如果是get请求就需要拼接参数
if(type == "get"){
url += data;
data = null; // 拼接后设置data为null,在send()方法中就不会再次发送
}
xhr.open(type,url);
// 请求头 如果是post才需要请求头
if(type == "post"){
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
// 请求体
xhr.send(data);
// 让异步对象接收响应
xhr.onreadystatechange = function(){
// 一个成功的响应有两个条件:1.服务器成功响应 2.数据解析完毕可以使用
if(xhr.status == 200 && xhr.readyState == 4){
// 接收响应的返回值 responseText responseXML
var rh = xhr.getResponseHeader("Content-Type");
if(rh.indexOf("xml") != -1){
var result = xhr.responseXML;
}
else if(rh.lastIndexOf("json") != -1){
var result = JSON.parse(xhr.responseText);
}else{
var result = xhr.responseText;
}
// 接收数据之后,调用回调函数
success && success(result)
}
}
},
}

封装代码的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dilireba.ajax({
type:'post',
url:'./server/nav-json.php',
data:{},
success: function (result){
var arr = [];
for(var i=0;i<data.length;i++){
var str = "<li>"
+ '<a href="#">'
+ '<img src="' + data[i].src + '" alt="">'
+ '<p>' + data[i].text + '</p>'
+ '</a>'
+ '</li>';
arr.push(str)
}
// 将生成的页面结构添加到dom元素中
document.querySelector("ul").innerHTML = arr.join("");
}
});
|