前后端分离项目
页面不在项目中, 通过axios异步请求与后端交互数据 , 这种请求有两个大问题:
第一就是跨域,
浏览器为了安全,对异步请求做出了限制,url不同(就是路径,协议,服务器,端口任何一个不同都属于)的请求直接报跨域
第二就是会话不携带cookie
解决:
对于跨域问题,解决就是在类上加一个@CrossOrigin(origins = {“xxxx”})的注解,
或者在mvc中配置<-mvc:cros/>
如果配有拦截器,被拦截住的请求就会被卡住解决不了跨域问题,所以配置个filter即可,详细看我建议代码快的filter解决跨域
对于不携带cookie需要分别在前端和后端都开启,允许接受和发送cookie
后端开启
这是注解配置的cros里
/**
* <mvc:cors/>
* @param registry
// */
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")//匹配所有路径
.allowedOrigins("*")//匹配所有的请求源
.allowedHeaders("*")//匹配所有请求头
.allowedMethods("*")//匹配所有请求方法
.allowCredentials(true);//允许跨域请求携带cookie
}
前端开启
这个是配置axios请求的全局设置.设置后用这个接受的变量去get,post就行了,
let javaNb = axios.create({
baseURL:`http://localhost:8080/`,//定义基础路径,用这个变量的axios请求自动拼接
withCredentials:true,//设置前端允许携带cookie
timeOut:5000
});
整好跨域和携带cookie以后,前后端分离项目就能用了, 接下来看看这种项目的注意的点
- 后端只负责传数据和状态,前端根据状态去跳转页面,所以要定义一个统一的返回值类
- 需要注意axios前后端的数组接受
javaNb.post(`deleteByMany`,this.ids)
//传数组不用整虚的,直接放post里他就是json了,
// 过去requestbody就能收,不管get还是post,给整成json,传过去就行
.then(success=>{}
@PostMapping("deleteByMany")
public Result deleteByMany(@RequestBody Integer[] ids){
log.info("接到删除参数:"+ Arrays.toString(ids));
}}
3.文件上传
part方式,在后端
@PostMapping("uploadPic")
public Result uploadPic(HttpServletRequest request) throws IOException, ServletException {
Part part = request.getPart("adv");
String fileName = part.getSubmittedFileName();
log.info("已接受前端上传文件"+fileName);}
在前端
这里需要注意的是,我如果在formdata.append方法的第三个参数加header,formdata对象就是一个空的, 后端接受的为[object object], 在post参数设置请求头就没事了
let formData = new FormData();
console.log(e.target.files[0])
formData.append("adv",e.target.files[0])//{headers:{"Content-Type":"multipart/form-data"}}
console.log(formData)
javaNb.post(`uploadPic`,formData,{headers:{"Content-Type":"multipart/form-data"}})//post请求参数默认为json,而文件为二进制文件,上传需要设置请求头为文件形式
.then(success=>{
console.log(success);
if (success.code == 2000){
this.imgURl = success.obj;//把默认头像换为更改后的值
}
})
文件下载的responseEntity参数,哪种项目都一样,写这方便复制,这里的attachment是固定写法,可以写其他的,好像最后都会识别为attachment
byte[] bytes = byteArrayOutputStream.toByteArray();//因为上传需要byte数组,不能直接上传流
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", URLEncoder.encode("工农信息表.xlsx","utf-8"));
ResponseEntity<byte[]> responseEntity = new ResponseEntity(bytes,headers, HttpStatus.OK);
return responseEntity;
异步请求项目
异步请求项目即页面用jQuery封装的Ajax请求后端,因为页面在项目中,所以访问页面的请求处理起来也很麻烦,加拦截器需要避开一堆静态资源, 这种方式的页面跳转,可以返回状态码在前端跳转,也可以在后端请求转发,异步请求的重定向无效哦
1.传递数组
前端
首先数据必须转为json格式,然后设置好请求头
var url = "deleteMany";
var p = JSON.stringify(ids);
$.ajax({
type: "post",
url: url,
data:p ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {}
后端
接受请求体
@PostMapping("deleteMany")
@ResponseBody
public Map<String,Object> deleteMany(@RequestBody Integer[] ids){
System.out.println(Arrays.toString(ids));
return bookService.deleteMany(ids);
}
2.文件上传
图片预览
//图片预览
$("#avater").on("change",function (e){
// 因为文件可以多选,所以是个数组,如果只有一张的话就是index为0的
var file = e.target.files[0];//拿到一个文件对象
var s = URL.createObjectURL(file);//拿到一个临时的 内存中对应文件对象的url,生命周期为dom,dom结束该url失效
$("#pic").attr("src", s);
});
前端
首先所有参数,都用formdata添加,
其次,processdata和contenttype全部设置为false,否则报错,不用改他们值,设为false好像就可以自动识别
//添加或修改确认事件
$("#addOrEdit").click(function (){
var formdata = new FormData();
formdata.append("part",$("#avater")[0].files[0]);
formdata.append("book_name",$("#bookName").val());
formdata.append("author_name",$("#authorName").val());
formdata.append("first_type_id",$("#firstType").val());
formdata.append("second_type_id",$("#secondType").val());
formdata.append("description",$("#description").val());
formdata.append("book_id",$("#hideId").val());
var url ="addBook";
$.ajax({
url: url,
type: "POST",
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
data: formdata,
success:function (data){
console.log(data)
if (data.code == 200){
alert("操作成功");
}else {
alert("操作失败");
}
queryByCondition();
}
})
});
后端
接受的时候,其他参数用对象接受即可, 文件对象用个request接或者直接用part接, 没有试过对象里放个part属性,不过我觉得应该也可以
@PostMapping("addBook")
@ResponseBody
public ResponseEntity addOrEditBook(Book book, HttpServletRequest req) throws IOException, ServletException {
Part part = req.getPart("part");
String finalPath = havePart(part, req);
book.setImg_url(finalPath);
Map<String, Object> map = bookService.addOrEditBook(book);
return ResponseEntity.ok().body(map);
}
同步表单提交项目
所有请求都是同步的, 页面跳转就依靠后端的请求转发和重定向, 前端所有请求都是一个表单,然后按钮请求,换页面都是依靠a标签来做,
前端必须指定enctype,才可以上传文件
<form class="layui-form" action="add" method="post" enctype="multipart/form-data"></form>
后端接受仍然如同上面说的异步
如果传递数组的话,必须得name值都一样,集合必须得封装对象之中
用jsp,还可以运用各种域对象操作