本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前后端交互
利用Cookie
Cookie 是一些数据, 存储于电脑上的文本文件中,只要客户端cookie开放且有数据,每一次请求都会自动添加到http报文中,后台可以实时接收观察获取这些Cookie 。
Cookie 的作用就是用于解决 "如何记录客户端的用户信息":
当用户访问 web 页面时,他的名字可以记录在 cookie 中。 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。 利用Session对象 session对象表示特定会话session的用户数据。
客户第一次访问支持session的JSP网页,服务器会创建一个session对象记录客户的信息。当客户访问同一网站的不同网页时,仍处于同一个session中。
request.getSession().setAttribute();
request.getSession().getAttribute();
只要浏览器不关闭,就能使用。所以用户访问网站整个生命都会用到的数据一般都用session来存储,比如用户名、登录状态之类的。
利用Request参数设置
request.setAttribute();
request.getRequestDispatcher("welcome.jsp").forward(request, response);
request.getAttribute();
不能用sendRedirect(),因为已经切换到另一个请求了,request参数的有效期为本次请求。
Ajax
前端用ajax发起请求。
window.onload=function(){
var jsondata={
"name":"Sarrans",
"password":"123456"
}
$.ajax({
type:"post",
url:"login",
data:jsondata,
success:function(data){
alert(data.name+"请求成功");
}
error:function(e){
alert("Error");
}
})
}
后台servlet接收请求处理
@WebServlet("/login")//ajax的url
public class login extends HttpServlet{
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
//从前端传递的request取值
String name=request.getParameter("name");
//构造一个新的json传回去
String s="{\"name\":\"Gerorge\",\"password\":\"1234567\"}";
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(s);//写入返回结果
//如果前台结果为success,会输出 Gerorge请求成功
}
}
jsonp
结合跨域方式,因为前端请求到数据需要在回调函数中使用,所以后端得将数据放回到回调函数中。
$.ajax({
url:"",
dataType:"jsonp",
jsonp:'callback',
success(function(res){
console.log(res)
})
})
性能改进
Comet
Comet的实现主要有两种方式,基于Ajax的长轮询方式和基于 Iframe 及 htmlfile 的流(http streaming)方式。而这些大部分功能在后台完成,前端要做的就是通过ajax请求成功后,在XMLHttpRequest的onreadystatechange函数中持续获取数据。
典型的Ajax通信方式也是http协议的经典使用方式,要想取得数据,必须首先发送请求。在低延迟要求比较高的web应用中,只能增加服务器请求的频率。Comet则不同,客户端与服务器端保持一个长连接,只有客户端需要的数据更新时,服务器才主动将数据推送给客户端。
var xhr=getXmlHttpRequest();
xhr.onreadystatechange=function(){
console.log(xhr.readyStae);
if(xhr.readyState===3&&xhr.status===200){
//获取成功后执行操作
//数据在xhr.responseText
console.log(xhr.responseText);
}
}
SSE
SSE是一种允许服务端向客户端推送新数据的HTML5技术。它是 WebSocket 的一种轻量代替方案,使用 HTTP 协议。
严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来要发送流信息时,客户端就会保持连接打开,SSE 使用的就是这种原理。
与由客户端每隔几秒从服务端轮询拉取新数据相比,这是一种更优的解决方案。
应用场景:例如邮箱服务的新邮件提醒,微博的新消息推送、管理后台的一些操作实时同步等.
var source=new EventSource("myevent");
source.onmessage=function(event){
console.log(event.data);
};
source.onerror=function(){
console.log("失败,连接状态"+source.readySate)
};
EventSource对象参数为入口点,必须与创建对象的页面同源(url模式,域、端口)。连接断开会自动建立,或者使用source.close()强制断开。open事件在连接建立时触发,message事件在接收到新数据时触发,error事件在无法建立连接时触发。推送数据保存在event.data中。
WebSocket
Websocket是一个全新的、独立的协议,基于TCP协议,与http协议兼容、却不会融入http协议。他被设计出来的目的就是要取代轮询和 Comet 技术。
WebSocket通过单个TCP连接提供全双工(双向通信)通信信道的计算机通信协议。此WebSocket API可在用户的浏览器和服务器之间进行双向通信。用户可以向服务器发送消息并接收事件驱动的响应,而无需轮询服务器。 它可以让多个用户连接到同一个实时服务器,并通过API进行通信并立即获得响应。
它允许用户和服务器之间的流连接,并允许即时信息交换。在聊天应用程序的示例中,通过套接字汇集消息,可以实时与一个或多个用户交换,具体取决于谁在服务器上“监听”(连接)。
WebSockets适用于需要实时更新和即时信息交换的任何应用程序。一些示例包括但不限于:现场体育更新,股票行情,多人游戏,聊天应用,社交媒体等。
var socket=new WebSocket("url");
socket.send("hello world");
socket.onmessage=function(event){
console.log(event.data);
console.log(event.readyState);
}
请求方式变化
jQuery ajax
传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。 JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持。
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
缺点:
本身是针对MVC的编程,不符合现在前端MVVM的浪潮 基于原生的XHR开发,XHR本身的架构不清晰。 JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务) 不符合关注分离(Separation of Concerns)的原则 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
fetch
fetch
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
优点:
符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里 语法简洁,更加语义化 基于标准 Promise 实现,支持 async/await 同构方便,使用 脱离了XHR,是ES规范里新的实现方式 更加底层,提供的API丰富(request, response) 缺点:
fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。 fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'}) fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费 fetch没有办法原生监测请求的进度,而XHR可以
axios
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
特点:
从浏览器中创建 XMLHttpRequest 支持 Promise API 客户端支持防止CSRF 提供了一些并发请求的接口(重要,方便了很多的操作) 从 node.js 创建 http 请求 拦截请求和响应 转换请求和响应数据 取消请求 自动转换JSON数据