一句话概括原理:
请求转发会导致功能模块的地址依然是注册的页面,只是展示的内容是其他页面的内容,刷新页面时重载的不是其他页面,而是注册的页面,就会导致注册页面中所有的方法——包括新增用户会被重复执行。
实例:
请求转发时,页面内容是showUser(新页面)的内容,但是地址栏还是saveUser(旧页面)的地址,此时执行页面刷新时,地址栏是旧页面的地址,就会被重复进入saveUser,而此时请求头中依然存在表单提交的数据,就会导致数据重复提交
doGet不会提示,直接重复提交数据
doPost会提示,点击确定后也会重复提交数据
下面是测试验证:
如果使用请求转发:
在doGet下:
①doGet存在信息泄露的风险
②页面显示的是新页面内容,但是地址栏还是旧页面的地址
③直接刷新页面时,网页不会提示“表单数据已经被使用过,重复提交可能导致重复操作”,直接再次访问旧页面的地址,并且重复读取请求头中的信息重复使用saveUser的新增数据的功能
在doPost下:
①信息没有存在地址栏上,不存在信息泄露
②刷新页面时会收到提示
③页面显示的是新页面内容,但是地址栏还是旧页面的地址
说明:
①数据不是从地址栏拿到的 而是请求中拿到的——doPost下重复刷新页面也会导致数据库重复添加数据
②刷新不会清除request 用户提交的表单信息依然存在——重复刷新页面时数据库重复添加的数据都是同一条
③刷新时浏览器会重载一次地址栏,地址栏指向的页面存在的所有方法(无论是doGet还是doPost)都会被重复执行,所以写在注册页面中的新增数据内容也会被重复触发
如果使用重定向:
在doGet下:
在doPost下:
说明:
①重定向时会改变地址栏,连带着规避掉doGet存在的表单信息泄露问题
②重定向后,刷新页面时浏览器重载的是新页面的地址,不是旧页面,所以不会重复调用saveUserServlet中添加用户的方法