前言
在日常开发中,我们常常会用到API接口,尤其是在客户端与服务器之间进行数据交互时,更是显得尤为重要,在本博客中,我将使用实例记录API接口调试的过程,以用于后期遇到同样问题时更快的解决。
问题描述
在之前其实也用到了第三方的API,第三方的API往往具备周全的说明文档,我们只需要按照文档对接口进行调用即可;但是在服务端和客户端都需要我们自己写时,往往会遇到一些问题。
在本次女装商城(前面博客提到过)中,我们需要使用商品ID来获取商品的详细信息,如商品名称、当前价格、商品原价以及图片等等,在之前的课程中,我们是直接发起POST请求,而无需传递参数,所以没有遇到任何问题,但是在需要传递商品ID时,遇到了POST请求传递的参数在服务端接受不到的问题。
Talend API Tester介绍
Talend API Tester是一款可以对API接口进行调试的谷歌浏览器插件,可以通过谷歌浏览器插件商城进行查找下载(由于众所周知的原因,需要一些工具进行操作,在本博客中不做详细说明)
除此之外,导师另外还推荐了一款应用程Postman:https://www.postman.com/
具体使用方法类似,Talend API Tester是浏览器插件,我个人觉得方便一点,所以用的这一款,看个人喜好。
数据接口展示【Django】
在本次接口中返回的后台数据为:
class GoodDetailDataAPIView(View):
"""
商品详情 数据接口
"""
def post(self, request): # post请求
data_id = request.POST.get('goodId') # 接收数据
print(data_id) # 打印接收数据
print(request.POST) # 打印接收所有POST数据
if data_id == '001':
data = {
'code': 0,
'message': 'success',
"data": {
"goodInfo": {
"amount": 10000,
"goodsId": "001",
"image1": BASE_RESOURCE_URL + 'goods/' + "001/cover.jpg",
"goodsSerialNumber": "6901435325888",
"oriPrice": 108.88,
"presentPrice": 98.88,
"shopId": "402880e860166f3c0160167897d60002",
"goodsName": "法国代购新款江疏影同款翻领修身中长裙春夏印花连衣裙",
"goodsDetail": '<img width="100%" height="auto" alt="" src="' + BASE_RESOURCE_URL + 'goods/' + '001/1.jpg" />' +
'<img width="100%" height="auto" alt="" src="' + BASE_RESOURCE_URL + 'goods/' + '001/2.jpg" />' +
'<img width="100%" height="auto" alt="" src="' + BASE_RESOURCE_URL + 'goods/' + '001/3.jpg" />' +
'<img width="100%" height="auto" alt="" src="' + BASE_RESOURCE_URL + 'goods/' + '001/4.jpg" />' +
'<img width="100%" height="auto" alt="" src="' + BASE_RESOURCE_URL + 'goods/' + '001/5.jpg" />'
}
}
}
# ...
# 这里添加了6条数据,格式和上述的一样
# if语句里分别是 == '002', '003', '004'...
else:
data = {
'code': 0,
'message': 'success',
"data": {}
}
# 返回JSON数据
return JsonResponse(data, safe=False)
接口url为:http://127.0.0.1:8000/shop/getGoodDetail
接口调试
- 点击谷歌浏览器右上角插件Talend API Tester,弹出Talend API Tester界面,点击左下角添加项目
- 输入项目名称,并点击创建
- 添加一个新的request
这里出现了一些问题,我常规的认为只需要在默认的request上修改请求方法为POST,然后在下方添加参数就可以了,但是,在返回结果中,没有得到我想要的数据。
接口调用
配置好API请求后,开始调用,但是在返回结果中,没有得到正确的数据。
原因分析:,可能是POST未接收到正确的参数,为验证这一结果,在控制台查看服务运行情况。
控制台果然没有打印接收到POST参数,这里就分析可能是HEADERS的问题。
查阅资料:
text/html :HTML格式
text/plain :纯文本格式
text/xml :XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png :png图片格式
application/xml : XML数据格式
application/json : JSON数据格式
application/pdf : pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如文件下载)
application/x-www-form-urlencoded :
<form encType="">中默认的encType,
form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)。
服务器收到的raw body会是,name=aaa&key=bbb。
multipart/form-data : 表单上传文件
资料来源于https://blog.csdn.net/luyu13141314/article/details/8112906
到这里就比较熟悉了,比如常见的前端Form表单直接上传文件时需要在form标签中添加enctype="multipart/form-data"属性;
再比如导师写的某接口文档里说明里的
以及在本门课程学习中遇到的
Future request(url, {formData}) async {
try {
Response response;
Dio dio = new Dio();
// 配置contentType
dio.options.contentType =
ContentType.parse('application/x-www-form-urlencoded').toString();
if (formData == None) {
response = await dio.post(servicePath[url]);
} else {
response = await dio.post(servicePath[url], data: formData);
}
if (response.statusCode == 200) {
return response;
} else {
throw Exception('后端接异常,请检查测试代码和服务器运行情况...');
}
} catch (e) {
return print('error:::$e');
}
}
修改Content-Type为application/x-www-form-urlencoded
问题依然没有解决,这时候经过了很长时间的调试,然后我认为可能是参数的问题,经过反复尝试,终于发现了问题。
这里还有个form,可以用来添加参数,我就试了一下
问题总结
该问题的产生是自己对接口调试的不熟悉产生的,那么为什么使用POST请求时将参数填写在上面的位置不可以,但是填写在body位置可以,或者说为什么GET请求可以,POST会出现问题呢?
答:Params处设置的变量请求时会将参数放在url后通过?传参(有点像GET方法传参数),而Body里设置的参数则是接口真正请求时发的参数。