数据交互
目前主流方式
- 表单: 最基本、最简单(
http所有的数据交互其实都是表单) ajax: 不用刷新,最常用,在服务器配合下也可以跨域jsonp: 较老的跨域方法,安全性太差,逐渐淡出websocket: 相对ajax性能比较高
对于服务器来说,是区分不了表单、ajax、jsonp,除非是人为标记。
表单
属性
action,提交地址method,提交方法GET,POST,PUT,HEADER,DELETE- 甚至自定义
- 表单项的
name必须使用,后端获取数据的key;可以重复,此时服务器获得的是数组 submit提交按钮
提交方法
GET,数据放在url中- 容量有限
- 能被用户看见(仅限于表单中的
GET) - 有缓存
- 利于分享和收藏(可以放在书签中)
POST,数据在请求体中- 容量大,但是过大(比如几个G的视频)也要使用其他方式
- 用户不可见
- 不缓存
- 没法分享和收藏
注意:GET和POST安全性完全一样,真正的安全方式https。
POST请求时两种Content-Type: multipart/form-data(文件上传时,在form标签中设定)、application/x-www-form-urlencoded
表单校验
绑定表单的submit事件
表单重复提交
- 开始提交时,禁用提交按钮
- 提交完成(成功/失败),重新启用提交按钮
ajax
- 依赖于
XMLHttpRequest对象,它本身是不兼容IE6的 IE6的ajax:ActiveObject
XMLHttpRequest
- 连接,
xhr.open(method, url, isAsync),isAsync是否异步- 同步:串行(在很多浏览器中
ajax的同步已被废弃) - 异步:并行
- 同步:串行(在很多浏览器中
- 发送,
xhr.send() - 接收,
xhr.onreadystatechange,xhr.readystate- 0 初始化,刚刚创建
- 1 已连接
- 2 已发送
- 3 已接收(头部)
- 4 已接收(body),此时需要查看
xhr.status(http状态码)
- 结果数据
xhr.responseText,文本数据xhr.responseXML,以XML返回的数据
get
let xhr = new XMLHttpRequest();
xhr.open('get', './index.php?a=3&b=2',true);
xhr.onreadystatechange = () => {
if(xhr.readyState===4){
if(xhr.status>=200 && xhr.status<300 || xhr.status===304){
console.log('成功:'+xhr.responseText);
}else{
console.log('失败:'+xhr.status);
}
}
};
xhr.send();
post
let xhr = new XMLHttpRequest();
xhr.open('post','./2.php', true);
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
console.log(xhr.responseText);
}else{
console.log('failed to load data');
}
}
};
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('a=2&b=3');
封装
以下是一个利用XMLHttpRequest对ajax进行手工封装的尝试:
/**
* @param {ajax请求选项} options
* 可能选项包括:url,type,data,datatype,success,error
* 默认参数:请求方式: get,请求参数:{},数据类型: text
*/
function ajax(options){
// 不兼容IE6
// 默认GET请求、普通文本、无参数
options = options || {};
options.data= options.data || {};
options.type = options.type || 'GET';
options.dataType = options.dataType || 'text';
// 将查询参数对象转为查询字符串
let dataArr = [];
for(let name in options.data){
dataArr.push(`${encodeURIComponent(name)}=${encodeURIComponent(options.data[name])}`);
}
let dataStr = dataArr.join('&');
// 新建xhr对象并open
let xhr = new XMLHttpRequest();
if(options.type.toLowerCase() === 'get'){
xhr.open('get', options.url+'?'+dataStr, true);
}else if(options.type.toLowerCase() === 'post'){
xhr.open('post', options.url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
// 绑定返回响应时间
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
let data;
switch(options.dataType.toLowerCase()){
case 'json':
if(window.JSON && JSON.parse){
data = JSON.parse(xhr.responseText);
}else{
data = eval('('+xhr.responseText+')');
}
break;
case 'xml':
data = xhr.responseXML;
break;
default:
data = xhr.responseText;
break;
};
options.success && options.success(data);
}else{
options.error && options.error();
}
}
};
// 发送
xhr.send(options.type.toLowerCase() === 'post' ? dataStr : null);
}
http状态码
- 1xx,消息
- 2xx,成功
- 3xx,重定向
- 301,永久重定向——浏览器永远不会再次请求老地址,不轻易用
- 302,临时重定向——一次性,浏览器下次还会请求老地址
- 304,
not modified,缓存,告诉客户端本地的缓存未被修改可直接用
- 4xx,请求错误(客户端)
- 5xx,服务端错误
- 6xx往后,扩展
重定向与转发
- 重定向:给浏览器的命令,让其向另一个地址发送请求,地址会改变
- 转发:在服务器内部,把请求交给另一个模块处理,对客户端是不可见的,地址不变
XML
XML早于HTML,也是由标签构成,但是没有固定的标签名,比json浪费空间。
jsonp
- 逐渐淡出,用于跨域
- 有安全性问题(过于开放,接口很容易能被他方调用)
ajax CORS跨域
websocket
formData
比较
ajax和表单比较
- 表单更稳定些(特别是在用户网络差的时候)
ajax,用户体验好些- 和场景也相关
ajax与websocket比较
ajax: 性能低,单向通信,跨域麻烦websocket: 性能高,双向通信(双工),默认可以跨域
跨域
- 浏览器同源策略初衷:安全,避免
XSS(Cross Origin Scripts),跨站脚本攻击 - 为什么需要跨域
- 一个公司的多个(比如新旧)网站
- 使用第三方数据交互
- 目前跨域方法
- 表单,比如表单方式的网银支付
ajax,麻烦jsonp,简单但不安全websocket,新兴,并还没有广泛支持;但是如果真的需要,也可以让其在低版本浏览器上运行
网络
OSI
OSI模型,即开放式通信系统互联参考模型(Open System Interconnection,OSI/RM,Open Systems Interconnection Reference Model),是国际标准化组织(ISO)提出的一个试图使各种计算机在世界范围内互连为网络的标准框架,简称OSI。该模型有七层(参考模型),实际用的是五层。
七层参考模型
- 物理层,物理学家、材料工程关注:材料、电压
- 链路层,内网寻址,
ARP、ICMP - 网络层,外网寻址,
IP - 传输层,通信稳定性,
TCP - 表现层,(统一各种网络的结构)
- 会话层,(让服务器记录以往访问状态)但是实际中都是无状态通信
- 应用层,应用细节,
HTTP(基于TCP)、FTP、SMTP、POP3
实际计算机网络的五层
- 物理层
- 链路层
- 网络层
- 传输层
- 应用层
两个协议
TCP,传输控制协议,(应用:文件下载、聊天、游戏),socket就是该协议- 保证到达
- 保证质量
- 保证顺序
UDP,用户数据报协议,(应用:对延迟要求高,对错误不敏感,如直播、视频电话)- 不保证到达
- 不保证质量
- 不保证顺序
http协议
连接过程
- 客户端与服务器连接:三次握手,客户端连接请求、服务器接受、客户端发送请求
- 请求与返回消息,
request和response- 消息头部(首部),<=32k
- 消息体(内容),<=1G
GET请求的数据是放在头部,所以容量很受限,而POST则可以发送大量数据
http与https
http,容易被窃听https,安全
版本
http1.0,一次性链接http1.1,保持链接,从而导致性能很大的提示http2.0,目前是草案,还没有彻底定稿- 强制
https - 自带双向通信
- 多路复用
- 强制
外话
安全性
- 系统级安全性,个人难以解决
- 代码安全性,程序员需要关注的,重要来源——蠢,懒,不重视
单点登录
OAuth,指多个客户端(比如淘宝、阿里云等)采用同一个验证服务器来进行登录验证。
RESTful
不是接口、不是标准,是一种风格、习惯;根据请求method和url共同决定接口访问的实际效果。
数据提交常用Content-Type
text/plain,纯文本application/x-www-form-urlencoded,urlencoded是指key=value&key=value形式(简单数据)multipart/form-data,用定界符分割各个数据(文件上传)