HTTP请求:前端与后端

经常碰到ajax请求传参,后端接收不到的问题。之前只是模糊的指导,前端传参格式与后端一致就可以。大多数就是直接拷贝已有的前后端代码做修改,没有深入、系统的了解过这块的东西。今天想了解了,却又不知道从何入手了。想了想,觉得从http协议入手比较好。

HTTP协议

整体的流程是:

  1. 客户端构造http请求(依据http协议的要求和自身需求,构造一定结构的数据)
  2. 发送数据(1中构造的结构数据,通过网络发送出去)
  3. 服务器接收数据并解析,然后返回一定结构的数据
  4. 客户端接收返回的数据并解析

请求协议结构:

  1. 请求行:请求方法 URL 协议版本
  2. 请求头:多行键值对
  3. 空行 :
  4. 请求体:任意的内容:字符串、二进制数据

    我们发起ajax请求时,最终都是构造成了这样的结构。
    所以我们需要考虑的是,我们前端构造的数据是怎样的,后端需要的数据是怎样的。

协议结构中,我们传业务相关的数据一般有两个位置。

  1. 请求行中的URL中,在?后面:key1=value1&key2=value2的形式传
  2. 请求体。可以是任何格式,但是为了前后端统一,会在请求头的content-type中保存下请求体保存的数据格式。

AJAX构造HTTP请求协议结构

前端浏览器、或者提供ajax请求的库,会将我们写的代码构造成http请求协议结构。以jquery为例:

	$.ajax({
		url:"/path?a=1&b=2",
		method:"post",
		data:{},
		contentType:""
	})
	最重要的就是上面的四个参数。

	$.ajax({
		url:"/path?a=1&b=2",
		method:"get",
		data:{}
	})
	$.ajax({
		url:"/path?a=1&b=2",
		method:"post",
		data:{},
	})
	$.ajax({
		url:"/path?a=1&b=2",
		method:"post",
		data:JSON.stringify({c:1}),
		contentType:"application/json"
	})

method默认为get时:

  1. contentType不起作用。
  2. data中的数据最终会自动追加到url的后面。
  3. data是对象时,会按属性拆成键值对进行追加

meghod为post时:

  1. contentType起作用(传到服务器端起作用,默认为“application/x-www-form-urlencoded; charset=UTF-8”。在解析中好像不起作用。在浏览器的调试窗口中,会用来解析请求数据的展示结构)
  2. data中的数据会添加到请求体中。
  3. data是对象时,会按属性拆成key1=value1&key2=value2形式
  4. data是字符串时,不解析

所以我们前端jquery构造的http请求协议数据常用的有一下三种:

1
get URL+kv数据

2
post URL+kv数据
content-type:‘application/x-www-form-urlencoded’
body:kv数据(key1=value1&key2=value2)

3
post URL+kv数据
content-type:‘application/json’
body:json字符串( ‘{“key1”:value1,“key2”:vlaue2}’ )

服务器端接收

服务器接口会解析URL后的数据,请求体中的数据。然后依据content-type进行解析。这里以springboot为例。

依次对应上面客户端构造的结构:
key1=value1&key2=value2这种的value本质传个字符串。你也可以传个json格式的字符串。springboot后端可以直接使用字符串接收,然后转换成相关类型。不知道springboot是不是也可以自动进行转换。试了下好像可以自动转数组,map和实体类的好像转不了,可能提供了自定义转换实现的入口。

	@RequestMapping(value = "/test1", method = RequestMethod.POST)
	@ResponseBody
	public String test1(@RequestParam(item) String item) {
		return "";
	}
	
	@RequestMapping(value = "/test2", method = RequestMethod.GET)
	@ResponseBody
	public String test2(@RequestParam(name) String name) {
		return "";
	}
	
	@RequestMapping(value = "/test3", method = RequestMethod.POST)
	@ResponseBody
	public String test3(@RequestBody Item item) {
		return "";
	}

总结下

前端jQuery,后端springboot的。直接这么用就成。

		$.ajax({
			url:"/path?a=1&b=2",
			method:"get",
			data:{}
		})
		$.ajax({
			url:"/path",
			method:"post",
			data:{
				name:"zhangs"
			},
		})
		$.ajax({
			url:"/path",
			method:"post",
			data:JSON.stringify({c:1}),
			contentType:"application/json"
		})
		
		@RequestMapping(value = "/test1", method = RequestMethod.GET)
		@ResponseBody
		public String test1(@RequestParam(a) String a,@RequestParam(b) String b) {
			return "";
		}
		
		@RequestMapping(value = "/test2", method = RequestMethod.POST)
		@ResponseBody
		public String test2(@RequestParam(name) String name) {
			return "";
		}
		
		@RequestMapping(value = "/test3", method = RequestMethod.POST)
		@ResponseBody
		public String test3(@RequestBody Item item) {
			return "";
		}

图片来源

补充

前端有时会用FormData构造参数。一般是post请求中,FormData数据会使用分割符,分割符需要在content-type中注明。
此时需要的ajax请求中需要processData和ontentType都设置为false。它会自动将content-type设置为:“multipart/form-data; boundary=----WebKitFormBoundaryWJwK1ZIKGijfvNQk”,“----WebKitFormBoundaryWJwK1ZIKGijfvNQk”这就是分隔符,好像是自动生成的。

		$.ajax({
			url:"",
			data:d2,
			processData: false,
			contentType:false, 
			method:'post'
		});
		
		@RequestMapping(value = "/test2", method = RequestMethod.POST)
		@ResponseBody
		public String test2(@RequestParam(name) String name) {
			return "";
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值