前后端数据交互,跳转

概述

作为一枚菜鸟,前后端交互可是大问题,经常数据交互失败,不知道怎么跳转。在这分享一下交互的小心得。

我们不妨先大概了解一下整个访问流程:

用户从输入网址按下回车,交互就已经开始了。

浏览器会将请求按照http协议(或者其他https,ftp等)将请求数据封装包从电脑的端口发出 -> 路由器 -> 运营商(域名解析之类的)-> 目标服务器(可能会有代理,负载均衡等等)

最终从服务器开放的端口,进入到服务器(TCP三次握手和四次挥手,Tomcat之类的,会根据协议的内容进行解析)-> web项目进行具体的逻辑处理 -> 返回数据 -> 浏览器接收数据(根据协议内容进行解析)

整个过程,协议很重要,因为客户端和服务器都是通过协议来解析和发送信息的,最常见的http协议,协议头部的参数常用的哪几个,有什么影响。

Http协议的简介,说的很有意思:https://blog.csdn.net/u010256388/article/details/68491509/

还有缓存问题(cookie、session、localstorage、cashe-controller等),不仅提高效率,而且有时候你更改了代码测试却没变化的重要原因:https://www.jianshu.com/p/9ed3e8759ce3

相应的后台tomcat的缓存处理:http://www.360doc.com/content/17/0721/17/41344223_673116604.shtml(了解即可)

具体到使用分为:前端交互,分为同步和异步。

同步交互

常见的from表单提交(post方式带参数),URL直接访问(get方式,有参数在地址栏可见,特殊符号需要转义,不安全)。

异步交互

关键是XMLHttpRequest对象,平时说的ajax只是一种交互模式,并不是什么新技术,其原理就是对XMLHttpRequest的封装。所以对XMLHttpRequest深入全面的了解可以帮助我们更好的掌握异步交互。

可以看这篇精品文章了解:https://www.jianshu.com/p/b037f71af548,里面涉及到了在传送过程中各个参数的用法,会触发的事件,返回值等等很实用的知识。(虽然能设置同步交互,但不推荐)

其中传输类型 contentType就非常重要,这个值设置决定了后台怎么去解析http协议。

  • 上图所示,如果格式前后端发送和接收对不上,那是获取不了数据。如图的最后一步返回,如果想页面跳转,则不需要@ResponseBody,改为返回ModelAndView
  • @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
  • @RequestParam接收的是key-value里面的参数,所以GET方式的数据和表单提交,可以接收。
  • @RequestBody和@RequestParma的使用知识,更轻松的全面掌握:https://blog.csdn.net/justry_deng/article/details/80972817

前端交互类

前端我创建了两个工具类,来负责交互。

异步交互类

我把jQuery的ajax进行了封装,主要是获取和计算信息,代码如下:

  1 /*
  2  * 以下为程序错误码
  3  */
  4 //通用的请求失败,包括未知原因
  5 var EXPECTATION_FAILED = 417;
  6 var EXPECTATION_QUERY = 404;
  7
  8 /**
  9  * 访问后台的对象,为ajax封装
 10  * @constructor
 11  */
 12 var Query = function (url, param, callback, contentType) {
 13     this.url = url;
 14
 15     //先确认参数存在,如果不存在则创建空map
 16     if (!param) {
 17         param = new Map();
 18     }
 19     //注意,要根据不同的传输格式来确定传输的值的类型
 20     if (contentType == Query.NOMAL_TYPE) {
 21         this.param = JSON.parse(this._convertParam(param));
 22     } else {
 23         this.param = this._convertParam(param);
 24     }
 25
 26
 27     this.callback = callback;
 28     this.contentType = contentType;
 29     //请求超时,默认5秒
 30     this.timeout = 5000;
 31     //是否异步请求,默认异步
 32     this.async = true;
 33 }
 34
 35 Query.JSON_TYPE = ‘application/json‘;
 36 Query.NOMAL_TYPE = ‘application/x-www-form-urlencoded‘;
 37
 38 /**
 39  * ajax请求的访问
 40  * @param url 要访问的地址
 41  * @param paramMap 传给后台的Map参数,key为字符串类型
 42  * @param callback 回调函数
 43  * @param contentType 传输数据的格式  默认传输application/x-www-form-urlencoded格式
 44  */
 45 Query.create = function (url, paramMap, callback) {
 46     return new Query(url, paramMap, callback, Query.NOMAL_TYPE);
 47 }
 48
 49 Query.createJsonType = function (url, paramMap, callback) {
 50     return new Query(url, paramMap, callback, Query.JSON_TYPE);
 51 }
 52
 53 /**
 54  * 将ParamMap转为json格式,目前只支持Map对象,以后会扩展
 55  * @param paramMap
 56  * @private
 57  */
 58 Query.prototype._convertParam = function (param) {
 59
 60     if (param instanceof Map) {
 61         return strMap2Json(param);
 62     }
 63 }
 64
 65 /**
 66  * 对ajax回调函数的封装
 67  * @param callBack
 68  * @private
 69  */
 70 Query.prototype._callback = function (queryResult) {
 71
 72     //取消加载框
 73     if (this.loadDom) {
 74         $(this.loadDom).remove("#loadingDiv");
 75     }
 76
 77     //Query对象
 78     var self = queryResult.queryObj;
 79     var data = $.parseJSON(queryResult.responseText);
 80     //记录请求是否有错误
 81     self.queryException = false;
 82     var handleError;
 83
 84     if (queryResult.status == EXPECTATION_FAILED || queryResult.status == EXPECTATION_QUERY) {
 85         var error = queryResult.responseText;
 86         self.queryException = true;
 87     }
 88
 89     //调用回调函数,如果返回结果为true,则对于出错不会默认错误处理
 90     if (self.callback instanceof Function) {
 91         handleError = self.callback(data);
 92     }
 93
 94     //如果出现了异常并且没有被处理,那么将进行默认错误处理
 95     if (self.queryException && !handleError) {
 96         window.location.href = "/system/error/" + error.code + "/" + error.msg;
 97     }
 98
 99     //如果需要跳转,则进行跳转
100     if (data.redirect_url) {
101         window.location.href = data.redirect_url;
102     }
103 }
104
105 /**
106  * 正式发送ajax
107  * @private
108  */
109 Query.prototype.sendMessage = function () {
110     var self = this;
111     var xhr = $.ajax(
112         {
113             type: "post",
114             url: this.url,
115             contentType: this.contentType,
116             data: this.param,
117             // ajax发送前调用的方法,初始化等待动画
118             // @param XHR  XMLHttpRequest对象
119             beforeSend: function (XHR) {
120                 //绑定本次请求的queryObj
121                 XHR.queryObj = self;
122                 if (self.beforeSendFunc instanceof Function) {
123                     self.beforeSendFunc(XHR);
124                 }
125
126                 if (self.loadDom instanceof HTMLElement) {
127                     self.loadDom.innerText = "";
128                     $(self.loadDom).append("<div id=‘loadingDiv‘ class=‘loading‘><img src=‘/image/loading.gif‘/></div>");
129                 } else if (self.loadDom instanceof jQuery) {
130                     self.loadDom.empty();
131                     self.loadDom.append("<div id=‘loadingDiv‘ class=‘loading‘><img src=‘/image/loading.gif‘/></div>");
132                 }
133             },
134             complete: this._callback,
135             timeout:this.timeout,
136             async:this.async
137         }
138     );
139
140 }
141
142 /**
143  * 检测是否有错误,返回ture有错误,或者false
144  */
145 Query.prototype.checkEception = function () {
146     return this.queryException;
147 }
148
149 //------------------------以下为对Query的参数设置---------------------------
150 /**
151  * 在ajax发送前设置参数,可以有加载的动画,并且请求完成后会自动取消
152  * @param loadDom 需要显示动画的dom节点
153  * @param beforeSendFunc ajax发送前的自定义函数
154  */
155 Query.prototype.setBeforeSend = function (loadDom, beforeSendFunc) {
156     this.loadDom = loadDom;
157     this.beforeSendFunc = beforeSendFunc;
158 }
159
160 /**
161  * 设置超时时间
162  * @param timeout
163  */
164 Query.prototype.setTimeOut = function (timeout) {
165     this.timeout = timeout;
166 }
167
168 Query.prototype.setAsync = function (async) {
169     this.async = async;
170 }

封装的好处:

  • 可以省略很多重复的代码,如$.ajax传参数那一长串(111-136行)
  • 可以规定统一的前端交互流程,并且修改这个流程也方便。
    1. 根据传输类型也对参数进行转换(20-24行),并且_convertParam()方法能继续扩展参数类型,直到后面可以把绝大多数参数都转换成正确的格式(那发送基本不用考虑参数格式了,只要确定传输的类型就好)    
    2. 统一回调流程(70-103行)可以对异常做统一处理(ajax)像我这样跳转到错误页面,或者有些异步请求返回时需要跳转,也能统一跳转
    3. 统一请求发送前的处理(119-133行)可以对请求等待统一的设置等待动画,最后再回调流程统一取消动画

同步交互类

from表单创建类,主要是进行有参数传输的页面跳转,因为直接URL跳转参数会暴露不安全

 1 /**
 2  * 访问后台的类,构造form表单来进行post请求
 3  * @param url
 4  * @param paramMap  参数map
 5  * @constructor
 6  */
 7 var QueryForm = function (url,paramMap) {
 8     //form表单的JQ对象
 9     this.form = $("<form></form>");
10     this.form.attr("action",url);
11     this.form.attr("method","post");
12     //遍历Map
13     for(var [key,value] of paramMap){
14        var inputDom = $("<input/>") ;
15        inputDom.attr("name",key);
16        inputDom.attr("value",value);
17        this.form.append(inputDom);
18     }
19     //必须要放入body里面,不然请求发不出去
20     var bodyDom = $("body");
21     bodyDom.append(this.form);
22     this.sendMessage();
23
24     //发送完后销毁
25     this.destroy();
26 }
27
28 QueryForm.create = function (url, paramMap) {
29     return new QueryForm(url,paramMap);
30 }
31
32 QueryForm.prototype.sendMessage = function () {
33      this.form.submit();
34 }
35
36 QueryForm.prototype.destroy =  function () {
37     this.form.remove();
38 }

后端交互类

普通的Controller,在@RequestMapping中填写正确的路径,根据前端传输的数据类型来获取参数(见上文),根据逻辑来确定要不要@ResponseBody来返回信息,还是ModelAndView来进行页面跳转

路径

经常404怎么办,那就是路径有问题。得先明白,java虚拟机运行的不是java文件而是编译后的.calss文件,所以最先检查的是target文件夹下是否有你URL写的这个文件,是否路径正确

平时网上看到的classpath,就是指target下的classes文件夹

顺带提一句,如果是eclipse,右键点击新建,你会发现有几个文件夹可以选

folder:就是普通的文件夹,它和我们window下面使用的文件夹没有任何区别

source folder:文件夹是一种特别的文件夹,如果你用面向对象的思想去看待这个source folder,那么他是folder的一个子集,作为子集,肯定是有folder的所有功能,而且还有自己特别的功能,他的特别之处,就是在source folder下面的java文件都会被编译,编译后的文件会被放在我们设置的某个文件夹下面(一般我们设置成WEB-INF/classes),source folder下面的非java文件会被copy一份放在我们的设置的文件夹下面

package:文件夹也是一种特别的文件夹,他的特别之处在于:他必须存在于source folder下面,上下级通过.来区分,他的路径最后组成了每一个类的包路径名

所以当出现404,请先检查路径,如果是springboot项目,则要遵守一些默认路径规则,比如模板必须放在templates,静态文件必须放在static

原文地址:https://www.cnblogs.com/top-housekeeper/p/11396460.html

时间: 2024-10-22 02:33:12

前后端数据交互,跳转的相关文章

前后端数据交互方法

在此介绍几种常用的前后端数据交互方法,并给出使用建议.以提高前后端协同开发的效率. 此文章适合前后端协同开发经验不足的新手阅读. 目录: HTML赋值 JS赋值 script填充JSON AJAX获取JSON WebSocket实时传输数据 总结 HTML赋值 输出到 Element 的 value 或 data-name <input type="hidden" value="<?php echo $user_avatar;?>" /> &

web前后端数据交互

前后端数据交互是每一名web程序员必须熟悉的过程,前后端的数据交互重点在于前端是如何获取后端返回的数据,毕竟后端一般情况下只需要将数据封装到一个jsonMap,然后return就完了.下面通过一个list.js来说明后端是如何将数据传到前端,前端是如何获取数据,并进行数据展示的. /** * 列表方法 * 1.列表页面显示列表内容的div容器ID为list_container * 2.列表页面模板区域textarea的ID为list_template * 3.列表页面显示列表页码下拉框的div容

前后端数据交互处理基于原生JS模板引擎开发

json数据错误处理,把json文件数据复制到----> https://www.bejson.com/ 在线解析json 这样能直观的了解到是否是json数据写错,在控制台打断点,那里错误打那里断点,观察是否有错误. <!DOCTYPE html> <html> <head> <title>前后端数据交互处理原生JS模板引擎开发</title> <meta charset ='utf-8'> <script type=&

前后端数据交互

前后端数据交互以及连接数据库流程: 首先需要在后台建立数据库,并且连接数据库,打开apache服务器确保所有文件代码在服务器中运行 这里是封装好的连接数据库通用模式(一定要确保数据库是否连接成功) 1:前端jsp页面设置form表单或是可以让用户提交用户信息的格式,确定需要传递的参数name让用户输入,通过点击按钮后submit()提交到后台: (这里是引用了bootsrap的模态框) 通过ajax传递参数(引用已经封装好的ajax) 自己封装好的ajax: function ajax(opti

Spring MVC前后端数据交互总结

控制器 作为控制器,大体的作用是作为V端的数据接收并且交给M层去处理,然后负责管理V的跳转.SpringMVC的作用不外乎就是如此,主要分为:接收表单或者请求的值,定义过滤器,跳转页面:其实就是servlet的替代品. - append Spring MVC在Web应用中扮演V的角色,负责处理HTTP请求并返回相应的资源,它在用的时候要配置一个核心的Dispatcher负责检查资源,请求过来的时候会查找是否有相应的Handler,有就会把请求交给Controller,一般使用注解来配置暴露给用户

实现前后端数据交互的方法

前端工程师的职责:1.UI重构  2.在正确的区域渲染出服务端的数据. 毕竟,我们要构建一个大的web应用,必然不是普普通通的静态页面构成. 下文将罗列前端工程师应该必备的同后端打交道的常用技能. 1.服务端渲染 谈起服务端渲染,对于动态服务而言,这个世界上跑的大多数页面都经过服务端的数据渲染,接口->前端赋值->模板渲染. 这些都是在服务器完成,在我们查看源码的时候,可以看到完整的html代码,包括每个数据值. 常用的php模板:Smarty,Blade,Mustache. 如果使用Node

vue 前后端数据交互问题解决

先在vue项目中配置好路由组件路由 然后写相应组件 2 后端 写接口赔路由 第三  解决跨域问题 处理数据交互 这样前端就拿到了数据 原文地址:https://www.cnblogs.com/tangda/p/10987082.html

spring mvc 前后端数据交互笔记(解决httprequest400,415问题)

1:前端发送数据,后端返回界面 A:浏览器 $.ajax({     url: "/rest/userController/login",     type: "post",     data: {"username": "chenhao", "password": "123456"} }); B:服务端 @RequestMapping("/login") publi

spring mvc 前后端数据交互笔记(解决415,400问题)

1:前端发送数据,后端返回界面 A:浏览器 $.ajax({ url: "/rest/userController/login", type: "post", data: {"username": "chenhao", "password": "123456"} }); B:服务端 @RequestMapping("/login") public String log