位置: IT常识 - 正文

前后端分离式交互(前后端分离弊端)

编辑:rootadmin
前后端分离式交互 目录

前言

1.javaEE环境安装

第一步:正常创建javase项目

第二步:右击项目,引入框架支持

第三步:将项目部署到Tomcat服务器上。Tomcat安装及配置

2.servlet搭建

请求格式为:ip:端口/项目名/servlet地址

3.servlet生命周期

4.http请求和响应

         4.1http请求

         4.2http响应:

5.过滤器(Filter)

6.异步请求(Ajax)+跨域问题

        6.1异步请求

        6.2跨域问题

         6.2.1什么是跨域?

         6.2.2为什么要跨域?

         6.2.3后端怎么解决跨域问题?

7.前端过渡

8.json数据格式+前端数据请求格式问题

       8.1后端数据响应json处理

       8.2前端请求数据格式处理

9.后端验证用户名和密码(联系数据库查询)

       9.1Reult类

       9.2User类

       9.3JDBC代码

       9.4.LoginServlet类

10.前端收到响应判断是否登录+sessionstorage+localStorage

     10.1前端接收到json字符串,做出判断

     10.2sessionstorage+localStorage

        10.2.1提出问题:

        10.2.2问题分析:

        10.2.3解决问题:

        10.2.4路由导航守卫

11.会话跟踪

    11.1token是怎么生成的?

    11.2token优点

    11.3base64转码

    11.4后端生成token并响应

    11.5前端接收到token后存储,并且请求时将token放在请求头

        11.5.1存储:

        11.5.2前端发送请求时(axios请求拦截):

    11.6后端通过过滤器中统一验证

    11.7前端接收到验证响应做出判断(axios响应拦截)


前言

推荐整理分享前后端分离式交互(前后端分离弊端),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:前后端分离式交互技术,前后端分离的作用,前后端分离原理,前后端分离优点,前后端分离与不分离,前后端分离式交互技术,前后端分离式交互,前后端分离式交互技术,内容如对您有帮助,希望把文章链接给更多的朋友!

        现在前端和后端已经完全分离,本篇文章会从javaEE环境的安装一直到会话跟踪结束,搭建一个学生管理系统的登录需求,实现前后端的基本交互。至于前端登录页面的搭建,是来源于于之前的文章前端项目框架的搭建(Vue.js+ElementUI骨灰级保姆教程)。切记细细理解代码中的注释!!!

1.javaEE环境安装

        项目是在IntelliJ IDEA 2020.2.1 版本下创建的。

第一步:正常创建javase项目

第二步:右击项目,引入框架支持

        选择Web Application(4.0) ,点击ok

         文件介绍

 第三步:将项目部署到Tomcat服务器上。Tomcat安装及配置

 

        Server设置成这样。 

 

        在Deployment 添加创建的项目。

 

完成此操作后,项目即已部署在服务器上。

2.servlet搭建

        导入servlet-api.jar包

        首先我们创建一个servlet包,里面创建LoginServlet类,此类继承HttpServlet类,在里面生成四个方法,分别是构造方法、init(ServletConfig config)、service()、destroy()。

import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServlet;import java.io.IOException;public class LoginServlet extends HttpServlet { public LoginServlet() { System.out.println("无参构造方法"); } @Override public void init(ServletConfig config) throws ServletException { System.out.println("初始化Servlet"); } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("service"); } @Override public void destroy() { System.out.println("destroy"); }}

        在xml文件中配置LoginServlet。

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置项目中的LoginServlet--> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>servlet.LoginServlet</servlet-class><!--LoginServlet在项目所处的位置--> </servlet> <!--为LoginServlet配置访问地址--> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/login</url-pattern><!--地址以/开头--> </servlet-mapping></web-app>

        然后启动服务器,在浏览器中访问:

请求格式为:ip:端口/项目名/servlet地址

         回车后,我们可以发现在后端输出框中输出了:

无参构造方法 初始化Servlet service

        为啥会输出这些?这就牵扯到了servlet生命周期~~~~~ 

3.servlet生命周期

         访问路线:

         方法解析:

package servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServlet;import java.io.IOException;/*!!!无论什么时侯创建,创建的servlet对象指向的是servlet地址, servlet什么时候被创建: 小于0:第一次访问服务器时,大于等于0:在服务器启动时 <load-on-startup>-1</load-on-startup> 在xml中配置 创建对象后就直接会执行构造方法和init(),之后访问到地址时(即通过浏览器-服务器-项目-地址),才会 执行service()等一系列方法。*//* * 一次http请求发送到后端找到Servlet程序,是按照一个特定的顺序调用方法 * 在最上层LoginServlet实现了Servlet接口,所有的javaEE的类都实现了Servlet接口,一切按照Servlet接口中定义方法的顺序来走。 */public class LoginServlet extends HttpServlet { // 构造方法() 最先执行 一次 初始化对象的,主要是针对成员变量 public LoginServlet() { System.out.println("无参构造方法"); } //init(ServletConfig config) 在构造方法之后就会执行 一次 初始化servlet,主要是针对配置文件,可获取到配置文件中定义的参数parameter,然后可通过config调用 /*<init-param> <param-name>zhangsan</param-name> <param-value>123</param-value> </init-param> */ @Override public void init(ServletConfig config) throws ServletException { System.out.println("初始化Servlet"); } //service() 每次请求都会执行,提供服务的。 @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("service"); } //destroy() 在服务器关闭时执行,只执行一次。比如将一些数据存储到数据库,打印日志信息。 @Override public void destroy() { System.out.println("destroy"); }}4.http请求和响应

         由于前端发送的http请求有get和post两种,所以后端提供doGet()和doPost()进行相应的处理和响应。

4.1http请求

        请求中包含:

请求行请求的地址,请求的方式,请求的状态。请求头包含服务器信息,客户端信息,以键值对的形式向后端发送,键都是固定的。请求体存放post请求方式向服务器端发送的数据。

        http请求的两种方式:

get:

          1.get方式主要用于从服务器获取数据,也是可以向服务器发送数据的后端地址?键=值&键=值。          2.不能传递过多的数据,因为浏览器会限制  一般情况 1-2kb。          3.请求的数据在地址后面显示的,不能传递敏感数据,安全性低。

         4.tomcat8之后,get请求中有中文,不会乱码。                     

post:        1.post主要用于向后端发送请求,请求的数据存放在请求体中,不会显示在地址栏中。        2.相对安全,传输的数据量大,没有限制(可以通过post提交文件)。 

       3.后端接受前、响应前需要设置编码,要不然接受时会乱码。setCharacterEncoding(编码格式)。

4.2http响应:

        1.Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个代表响应的HttpServletResponse对象。

        2.用getWriter()获得一个PrintWriter字符输出流输出数据                3.response.setContetnType("text/html;charset=utf-8");方法可以同时设定response所使用的字符集编码和浏览器打开所用的字符集编码。

        前端发送(举例):

<!DOCTYPE html><html><head><meta charset="utf-8" /><title></title></head><body> <!--get方式--><a href="http://127.0.0.1:8080/webBack_Test/login?name=ami&age=20">同步访问后端</a> <!--post方式--><form action="http://127.0.0.1:8080/webBack_Test/login" method="post">用户名<input type="text" name="username" value="" />密码<input type="password" name="password" value="" /><input type="submit" value="登录"/></form></body></html>

         后端接收:

public class LoginServlet extends HttpServlet { /* 虽然调用doGet和doPost方法,但是构造,init,service,destroy方法,仍然会正常执行,这是Servlet接口的规范,是不能变的!! 其实父类的service方法,里面是会进行一个判断的,判断请求方式是get还是post,然后调用doGet()或者doPost()方法, 只不过之前我们在本类中又重写了service方法,使他的实际功能没有体现出来。 当一次http请求发送到服务器时,tomcat会将请求的所有数据封装到一个类当中,而这个类实现了HttpServletRequest接口。 * */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* get与post的接收顺序,步骤一样,就是doGet里面不用设置编码 * */ } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接收请求数据(请求行,请求头,请求体) req.getRequestURL();//http://127.0.0.1:8080/webBack_Test/login req.getRemoteAddr();//获取远端的ip地址 127.0.0.1 req.getRemotePort();//获取远端的端口 //接收用户自己发来的数据.post数据在接受之前,需要设置一个解码规则 req.setCharacterEncoding("utf-8"); req.getParameter("username"); req.getParameter("password"); //处理 //响应 //resp.setContentType("text/html;charset=utf-8");设置编码 resp.setHeader("Content-Type","text/html;charset=utf-8"); PrintWriter writer = resp.getWriter();//获取打印流 writer.print("提交成功"); //对象,集合,map-->以后用json //print与write没区别,就是print的方法重载比较多 }}5.过滤器(Filter)

        我们知道在前端发送post请求时,后端接收时要先设置编码,以防止乱码,如果项目中servlet包有多个类时,每一个在接受前都要手动设置一下编码,岂不繁琐。所以我们提出过滤器。

        Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。

      Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Servlet, 从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

      ● doFilter(ServletRequest request, ServletResponseresponse,FilterChain chain):该方法是filter进行过滤操作的方法,是最重要的方法。

      ●  filterChain过滤链,处理完后,让请求继续向下执行,下一个可能时目标Servlet,也可能是下一个过滤器。         filterChain.doFilter(servletRequest,servletResponse);

        作用:对服务器web资源进行拦截(权限控制,通过拦截资源进行权限控制,是否可以访问)

         即浏览器访问服务器时,可以进入过滤器1、也可访问servlet地址。如果进入到过滤器1后,可以继续进到过滤器2、也可直接截止做出响应、也可继续访问servlet地址,都是我们可以设置的!

        所以我们可以创建一个filter包里面创建一个设置编码的过滤器(类),让每次请求先通过编码过滤器,设置编码。

/*编码过滤器*/public class EncodeFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); //filterChain过滤链,处理完后,让请求继续向下执行,下一个可能时目标Servlet,也可能是下一个过滤器 filterChain.doFilter(servletRequest,servletResponse); }}

       在xml文件中配置过滤器:配置/*表示所有请求都得过此过滤器

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置项目中的LoginServlet--> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>servlet.LoginServlet</servlet-class><!--LoginServlet在项目所处的位置--> </servlet> <!--为LoginServlet配置访问地址--> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/login</url-pattern><!--地址以/开头--> </servlet-mapping> <!--配置编码过滤器--> <filter> <filter-name>encode</filter-name> <filter-class>filter.EncodeFilter</filter-class> </filter> <filter-mapping> <filter-name>encode</filter-name> <url-pattern>/*</url-pattern> <!--配置哪些请求地址进入到编码过滤器 /*表示所有--> </filter-mapping></web-app>6.异步请求(Ajax)+跨域问题        6.1异步请求

        说起异步,涉及的领域很广,这里我们探讨异步请求。下面是同步请求和异步请求之间的区别。

前后端分离式交互(前后端分离弊端)

         以前javaScript里的异步请求(用户名失焦验证举例):

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><script type="text/javascript">function checkusername(username){//最底层代码,是用XMLHtttpRequest对象来发送请求var httpObj = new XMLHttpRequest();httpObj.open("GET","http://127.0.0.1:8080/webBack/login?username="+username,true);httpObj.send(null);//发送请求//接受请求httpObj.onreadystatechange=function(){//就相当于一个状态信息码 从2开始--到4响应结束if(httpObj.readyState==4){document.getElementById("msgId").innerHTML = httpObj.responseText;}} </script></head><body><form action="" method="post">账号<input type="text" name="username" value="" onblur="checkusername(this.value)" /><span id="msgId"></span> <br />密码<input type="password" name="password" value="" /><br /><input type="submit" value="登录"/></form></body></html>

        现在用axios,是一个Ajax框架来进行改进,但是底层还是通过XMLHtttpRequest对象来操作的。此时我们还未把我们所讲的东西整合在Vue-cli(脚手架)项目中,所以我们需要导入一个axios.min.js的js文件。axios.min.js下载

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><script src="js/axios.min.js" type="text/javascript" charset="UTF-8"></script><script type="text/javascript">function checkusername(username){//将创建XMLHtttpRequest对象的过程封装在了get()里面axios.get("http://127.0.0.1:8080/webBack_Test/login?username="+username).then(function(resp){ //resp就是拿到的一系列响应过来的数据 document.getElementById("msgId").innerHTML = resp.data;});}</script></head><body><form action="" method="post">账号<input type="text" name="username" value="" onblur="checkusername(this.value)" /><span id="msgId"></span> <br />密码<input type="password" name="password" value="" /><br /><input type="submit" value="登录"/></form></body></html>

         运行之后会发现,浏览器发出请求给服务器,可是服务器响应,浏览器接收不到,这就引出了跨域问题。 之前我们同步请求时,服务器的响应是直接响应在浏览器重新生成的窗口上,而异步请求时服务器的响应是要被浏览器给接收到的,然后通过标签响应在此页面上。

        6.2跨域问题            6.2.1什么是跨域?

        跨域是指从一个域名的网页去请求另一个域名的资源,严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域.

        跨域问题是一个前端问题,是在前后分离的架构中出现的。

         6.2.2为什么要跨域?

        有时公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。

        6.2.3后端怎么解决跨域问题?

解决办法是创建一个过滤器(CorsFilter)。

import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;//后端解决跨域问题public class CorsFilter implements Filter { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; //允许携带Cookie时不能设置为* 否则前端报错 //1.本质就是你浏览器在访问服务器时,我后端获取到你浏览器的地址,然后设置前端让前端知道这是一个安全的响应,即后端响应可以到浏览器上 //就比如说,你浏览器是8848的端口,你访问我8080的服务器,我给你做出响应,你不接收,我后端就就要设置8848要可跨域。 httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域 httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等 httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头 httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie filterChain.doFilter(servletRequest, servletResponse); }}

在xml中配置cors过滤器。

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置项目中的LoginServlet--> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>servlet.LoginServlet</servlet-class><!--LoginServlet在项目所处的位置--> </servlet> <!--为LoginServlet配置访问地址--> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/login</url-pattern><!--地址以/开头--> </servlet-mapping> <!--配置编码过滤器--> <filter> <filter-name>encode</filter-name> <filter-class>filter.EncodeFilter</filter-class> </filter> <filter-mapping> <filter-name>encode</filter-name> <url-pattern>/*</url-pattern> <!--配置哪些请求地址进入到编码过滤器--> </filter-mapping> <!--配置解决跨越过滤器--> <filter> <filter-name>cors</filter-name> <filter-class>filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>7.前端过渡

        现在我们把Ajax加到我们之前用vue写的前端项目(vue-cli)里面,项目是之前用脚手架方式搭建的,感兴趣的友友们可以看一下:前端项目框架的搭建(Vue.js+ElementUI骨灰级保姆教程)。

        在终端中输入命令:npm install axios

        之前我们在main.js里面导入了路由和ElementUI框架,现在把axios也加进去。 

       

        发送post请求方式为:

this.$http.post("请求地址",需要传输的数据).then((resp)=>{          });

8.json数据格式+前端数据请求格式问题        8.1后端数据响应json处理

        JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,是为了在不同语言间传输数据方便,我们知道java和javaScript的语法是不一样的,那么我们在前后端之间的数据传输就要用到json。

        转换代码: 

ObjectMapper objectMapper = new ObjectMapper();    //创建对象 String json = objectMapper.writeValueAsString(响应的数据);//将响应的数据转化为字符串

       利用writeValueAsString()方法可以将要响应的数据,例如对象,转化为一个json字符串,前端接收到json字符串后,自动会转换为js对象。

        例如:

{"code":200,"data":{"id":1,"username":"zhangsan","password":null},"msg":"登录成功"}

        要使用json数据交换格式,我们需要在lib目录里面导入6个json的jar包。

         8.2前端请求数据格式处理

        我们在用vue框架前,前端请求数据都是以键值对的,例如 username = "  ",这样后端就用getparameter("键名")方法,能够获取到数据。而当我们使用了vue框架后,里面的数据格式会不同,例如 usernam : "  ",这样就会导致数据传输到后端,但是后端getparameter("键名")方法读取不到。所以我们要在前端对数据进行处理。我们自定义一个转换函数~~~

//序列化为键=值&键=值

function jsonToString(jsonobj){            console.log(jsonobj)            var str = "";            for(var s in jsonobj){                 str+=s+"="+jsonobj[s]+"&";                  }            return str.substring(0,str.length-1);        }

 即发送请求方式为:

         this.$http.post("login",jsonToString(this.ruleForm)).then((resp)=>{  });

ruleForm为我们提交的表单中的数据,里面包含username,password。

9.后端验证用户名和密码(联系数据库查询)

        结合上面我们所讲的知识,联系起来,搭建基本的后端代码。

                9.1Reult类

        为了响应数据格式统一,我们创建一个Reuslt类,用来封装每次后端响应的数据。

public class Result { int code;//200成功 201失败 Object data;//数据 user对象 String msg; //信息提示 public Result(int code, Object data, String msg) { this.code = code; this.data = data; this.msg = msg; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public static Result success(Object data){ //操作成功 return new Result(200,data,"登录成功"); } public static Result warn(){ //登录失败 return new Result(201,null,"账号或密码错误"); } public static Result error(String msg){ //出现异常 return new Result(500,null,msg); }}      9.2User类

        查询前实例化一个user对象,将查询的结果储存在user里面,没查询到user即为null

public class User { private int id; private String username; private String password; private String token; //会话跟踪处要用 public User() { } public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; }}        9.3JDBC代码

        联系数据库、通过JDBC查询返回User。代码相信大家都能理解,不做过多解释。

public class LoginDao { static Connection con = null; static PreparedStatement pst = null; static ResultSet rs = null; public static User find(String username,String password) throws SQLException { User user = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai", "root", "root"); String sql = "select * from user where username = ? and password =?"; pst = con.prepareStatement(sql); pst.setObject(1,username); pst.setObject(2,password); rs = pst.executeQuery(); while (rs.next()) { user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(null); } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); }finally { if(con!=null){ con.close(); } if(pst!=null){ pst.close(); } if(rs!=null){ rs.close(); } } return user; }}        9.4.LoginServlet类

        通过ObjectMapper对象,将result转化为json字符串,响应到前端。

public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Result result = null; //要通过编码过滤器,所以不用设置编码。 //接收数据 String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println(username); //打印一下,以便于看一下后端接收到前端发送的数据了没 System.out.println(password); //设置响应编码 resp.setHeader("Content-Type","text/html;charset=utf-8"); //获取打印流 PrintWriter writer = resp.getWriter(); //处理 访问dao 与数据库交互,根据返回的结果向客户端响应内容 try { User user = LoginDao.find(username,password); if(user!=null){ result = Result.success(user); }else { result = Result.warn(); } } catch (SQLException e) { e.printStackTrace(); result = Result.error("系统忙"+e.getMessage()); } //两种语言间对象结构不同,需要一种标准格式进行数据传输,json是一个轻量级的格式。 ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(result); System.out.println(json); writer.print(json); }}10.前端收到响应判断是否登录+sessionstorage+localStorage       10.1前端接收到json字符串,做出判断 //如果发送成功,在此向用户提示,并跳转到登陆成功的组件this.$http.post("login",jsonToString(this.ruleForm)).then((resp)=>{//resp.data = Result 前端接收到json字符串后,自动会转换为js对象。 resp.data其实就是拿到了json字符串,只不过它可以看作是user对象if(resp.data.code==200){//直接跳转 this.$message({message: '登录成功',type: 'success'});//提示信息都是ElementUI里面的 this.$router.push("/main"); //路由切换,切换进主页面 }else if(resp.data.code==201){ this.$message({message:resp.data.msg,type: 'warning'});//提示信息}else{ this.$message.error(resp.data.msg);//提示信息}});    10.2sessionstorage+localStorage

        我们现在实现了到登录界面输入用户名和密码,然后提交表单到后端,后端查询后做出响应给前端,前端做出判断是否登录成功。

        10.2.1提出问题:

        但是现在有个问题,就是如果我们不通过登录页面,而是直接访问主界面,那么也会访问的到,并且如果我们关闭主界面,或者退出主界面,然后再访问主界面,它依旧是可以直接跳转到主界面,没有通过登录就可以访问主界面,这些显然是不切合实际的。

        10.2.2问题分析:

        那我们试想有没有这样一种东西,我们每次登录成功后把用户名存在浏览器里面,然后每次跳转到其他页面(除过跳转登录页面)时,我都要做一次判断,看一下浏览器里面有没有用户名信息,如果没有的话,则跳转至登录页面,表示要重新登陆!

        10.2.3解决问题:sessionstorage浏览器提供的一个会话级别的存储空间,浏览器关闭后立刻消失.setItem("键",值);localStorage长久保存到浏览器。只能手动清除setItem("键",值)

         这里用sessionstorage就可以解决我们的问题:sessionStorage.setItem("username",用户名);

登录成功后将用户名信息存储即可,不仅在关闭页面后,需要清空存储。我们还得在主界面退出登

录的时候也得将存储清空。

         主界面退出函数:

exit(){this.$confirm('你确定要退出此窗口?', '提示', { confirmButtonText: '确定', type: 'warning'}).then(() => {sessionStorage.clear();//清除sessionStorage缓存 this.$router.push("/login"); }); }

        改进过后的登录判断(将用户名信息存储):

//如果发送成功,在此向用户提示,并跳转到登陆成功的组件this.$http.post("login",jsonToString(this.ruleForm)).then((resp)=>{//resp.data = Result 前端接收到json字符串后,自动会转换为js对象。 resp.data其实就是拿到了json字符串,只不过它可以看作是user对象if(resp.data.code==200){//直接跳转 sessionStorage.setItem("username",resp.data.data.username); this.$message({message: '登录成功',type: 'success'});//提示信息都是ElementUI里面的 this.$router.push("/main"); //路由切换,切换进主页面 }else if(resp.data.code==201){ this.$message({message:resp.data.msg,type: 'warning'});//提示信息}else{ this.$message.error(resp.data.msg);//提示信息}});         10.2.4路由导航守卫

        在我们路由(页面)每次想跳转时,我们都要自己在要切换的路由里mounted(当vue对象于标签绑定完毕后执行,类似于onload事件)添加判断信息:

mounted(){this.username = sessionStorage.getItem("username");if(this.username==null){ this.$router.push("/login");} }

        这样特别麻烦,因为在我们的主界面得有很多操作,都得添加判断,在这我们引出路由导航守卫来改进。在router目录里index.js文件里添加。文件在前端项目框架的搭建(Vue.js+ElementUI)

里面都有讲过。感兴趣的友友可以了解一下~~~

import Vue from 'vue';import router from 'vue-router'; /* 导入路由*//* 导入组件 */import Login from "../Login.vue"; //../返回上一级目录import Main from "../Main.vue";Vue.use(router);/* 定义组件路由 */var rout = new router({routes: [{path: '/login', //为组件定义地址name: 'Login', //自己起一个名字 也可以不用起名component: Login //与上面导入的名字必须对应一致},{path: '/main',component: Main}]}); //在router里面的index.js文件里加入路由导航守卫,每次发生路由时触发//to:要访问的路由 from:请求访问的路由 next:跳转rout.beforeEach((to,from,next)=>{if(to.path=='/login'){ //如果用户访问的登录页,直接放行return next();}else{var username = sessionStorage.getItem("username");if(username==null){return next("/login");//跳转到登录页面}else{return next();//继续}}}) //导出路由对象export default rout;11.会话跟踪

        因为http的请求都是无状态的(请求--响应的模式),请求中并没有能识别对方身份的标识,那么我们在实际开发中就要解决这个问题,假如:我们在网上购物,虽然我们登录过了,然后点击付款,这个付款请求中没有携带用户信息,所以后端不知道是哪个用户请求的。

        这个实现的功能称为web会话跟踪技术。

      11.1token是怎么生成的?

        token是由三部分组成,第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 用户的信息),第三部分是签证(signature),将这三段信息文本用.链接一起就构成了token字符串。

        例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

        头信息(header):

完整的头部就像下面这样的JSON:

 {

  'typ': 'JWT',             

本文链接地址:https://www.jiuchutong.com/zhishi/298921.html 转载请保留说明!

上一篇:【深度学习】pix2pix GAN理论及代码实现与理解

下一篇:web自动化测试入门篇06 —— 元素定位进阶技巧(web自动化测试平台)

  • 微软账户登录一直转圈是什么原因(微软账户登录一直白屏)

    微软账户登录一直转圈是什么原因(微软账户登录一直白屏)

  • 微信朋友圈广告评论是自动评论的吗(微信朋友圈广告怎么关闭不了)

    微信朋友圈广告评论是自动评论的吗(微信朋友圈广告怎么关闭不了)

  • 美团拼团后其中一个人能退嘛(美团拼团后其中一个订单)

    美团拼团后其中一个人能退嘛(美团拼团后其中一个订单)

  • 微信仅部分可见安全么(微信仅部分可见怎么取消)

    微信仅部分可见安全么(微信仅部分可见怎么取消)

  • 手机扫描表格怎么生成表格?(用手机扫描表格)

    手机扫描表格怎么生成表格?(用手机扫描表格)

  • 苹果手机天气怎么定位(苹果手机天气怎么设置)

    苹果手机天气怎么定位(苹果手机天气怎么设置)

  • 抖音关注请求是对方发的吗(抖音关注请求是对方发过来的吗)

    抖音关注请求是对方发的吗(抖音关注请求是对方发过来的吗)

  • 路由器做交换机稳定吗(如何把路由器当交换机)

    路由器做交换机稳定吗(如何把路由器当交换机)

  • 淘宝过了七天无理由还可以退货吗(淘宝过了七天无理由)

    淘宝过了七天无理由还可以退货吗(淘宝过了七天无理由)

  • 高德地图如何关闭hud模式(高德地图如何关闭新手模式)

    高德地图如何关闭hud模式(高德地图如何关闭新手模式)

  • 华为手写输入法不见了(华为手写输入法 手写板)

    华为手写输入法不见了(华为手写输入法 手写板)

  • 华为荣耀9x能不能快充(华为荣耀9X能不能开空调)

    华为荣耀9x能不能快充(华为荣耀9X能不能开空调)

  • vivo怎么看自己手机号(vivo怎么看自己的评论)

    vivo怎么看自己手机号(vivo怎么看自己的评论)

  • 苹果8换铃声怎么换(苹果8换铃声怎么弄)

    苹果8换铃声怎么换(苹果8换铃声怎么弄)

  • word2003怎么画线条(word2003画线条在哪里)

    word2003怎么画线条(word2003画线条在哪里)

  • 收藏在手机哪里找(手机收藏的东西在哪里找)

    收藏在手机哪里找(手机收藏的东西在哪里找)

  • i12 tws耳机是什么牌子的(i12耳机是什么意思)

    i12 tws耳机是什么牌子的(i12耳机是什么意思)

  • 小度1s怎么绑第二个手机(小度1c怎么绑定小度app)

    小度1s怎么绑第二个手机(小度1c怎么绑定小度app)

  • 闲鱼怎么加入鱼塘(闲鱼怎么加入鱼小铺)

    闲鱼怎么加入鱼塘(闲鱼怎么加入鱼小铺)

  • Vben Admin框架 table的使用以及相关的内容(vben admin框架怎么实现上传文件时拿到文件参数)

    Vben Admin框架 table的使用以及相关的内容(vben admin框架怎么实现上传文件时拿到文件参数)

  • 常用激活函数activation function(Softmax、Sigmoid、Tanh、ReLU和Leaky ReLU) 附激活函数图像绘制python代码(常用激活函数及其导数)

    常用激活函数activation function(Softmax、Sigmoid、Tanh、ReLU和Leaky ReLU) 附激活函数图像绘制python代码(常用激活函数及其导数)

  • 什么叫征期抄税?
  • 产权转移书据印花税包括什么
  • 超率累进税率定义
  • 收到的税费返还应在支付的税费项目中扣除判断题
  • 公司取得违约金合法吗
  • 医院能否开具增值税专用发票
  • 黄金销售免税
  • 无形资产开发阶段计入什么科目
  • 填第二季度的利润总额怎么填
  • 万元版和十万元版可以一起用吗
  • 期间费用包括资本公积吗
  • 城建税如何核算成本
  • 结转产成品会计分录怎么做
  • 高新企业如何结转成本
  • 出纳在银行领了钱出纳要怎样记帐?
  • 应付账款不用付了摘要怎么写
  • 衍生金融资产的核算
  • 免税的投资收益需要调整利润表吗
  • 房屋租赁费发票可以抵扣吗
  • 无票收入记账多的进项发票怎么处理?
  • 实收资本印花税税率多少
  • 蔬菜批发的利润怎么算
  • 个体户财务负责人风险有哪些
  • 失控发票的账务处理
  • 差旅费税务要求比例
  • 外贸企业申报出口退税商品名称可以改吗
  • 缴纳残保金和工龄有关吗
  • 如何固定iPhone墙纸
  • 暂估成本跨月账务处理
  • 公司流水账是会计做吗
  • php 多维数组转换成字符串
  • 社保公积金的钱可以提出来吗
  • 记账凭证的摘要怎么填写
  • linux用不了yum
  • 圣海伦斯山国家火山纪念区
  • linux中的文件
  • php b/s
  • 公司为员工缴纳社保的基数怎么确定
  • 玄武湖公园游玩
  • zendframework3
  • html调查问卷简单代码
  • 联邦学习攻击与防御综述
  • cookie from
  • 处置固定资产清理费用影响利润吗
  • 增值税进项税额能不能抵扣
  • 股权划转有税费吗
  • 企业所得税如何征收
  • 织梦上传图片大小设置
  • 自然人税收管理系统扣缴客户端官网
  • 旅游公司差额征税如何开票
  • 政府会计应付职工薪酬明细科目
  • 增值税纳税申报实训报告
  • 购买商品并入库做什么会计分录
  • 乡村道路属于城市道路吗
  • 坏账准备是什么凭证
  • 坏账损失的会计核算方法
  • 农村土地征用补偿价格
  • 商业承兑汇票贴现流程
  • 什么是大病医疗救助
  • 金蝶多核算项目怎么查一个项目下的其他项目
  • sql server233错误
  • win7系统怎么运行xp系统的软件
  • 苹果电脑如何缩小屏幕显示
  • win xp 系统
  • 写出10个linux系统操作命令和用法
  • win10注册表的作用
  • Win7电脑屏幕横过来了怎么恢复
  • windows10预览
  • linux yw命令
  • cocos怎么用
  • python让用户选择
  • javascript基础笔记
  • jquery插件怎么用到自己的网站
  • js怎么定义类
  • 四川省税务局发票查询
  • 支部组织生活会流程
  • 江苏地税局官网网站
  • 地税开发票税率是多少
  • 营业执照增加项目怎么办理
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设