前言

  在日常开发中,我们常常会用到API接口,尤其是在客户端与服务器之间进行数据交互时,更是显得尤为重要,在本博客中,我将使用实例记录API接口调试的过程,以用于后期遇到同样问题时更快的解决。

问题描述

  在之前其实也用到了第三方的API,第三方的API往往具备周全的说明文档,我们只需要按照文档对接口进行调用即可;但是在服务端和客户端都需要我们自己写时,往往会遇到一些问题。
  在本次女装商城(前面博客提到过)中,我们需要使用商品ID来获取商品的详细信息,如商品名称、当前价格、商品原价以及图片等等,在之前的课程中,我们是直接发起POST请求,而无需传递参数,所以没有遇到任何问题,但是在需要传递商品ID时,遇到了POST请求传递的参数在服务端接受不到的问题。

Talend API Tester介绍

  Talend API Tester是一款可以对API接口进行调试的谷歌浏览器插件,可以通过谷歌浏览器插件商城进行查找下载(由于众所周知的原因,需要一些工具进行操作,在本博客中不做详细说明)
  除此之外,导师另外还推荐了一款应用程Postman:https://www.postman.com/

具体使用方法类似,Talend API Tester是浏览器插件,我个人觉得方便一点,所以用的这一款,看个人喜好。

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

接口调试

  1. 点击谷歌浏览器右上角插件Talend API Tester,弹出Talend API Tester界面,点击左下角添加项目
    添加项目

  2. 输入项目名称,并点击创建
    添加项目

  3. 添加一个新的request
    image.png
    这里出现了一些问题,我常规的认为只需要在默认的request上修改请求方法为POST,然后在下方添加参数就可以了,但是,在返回结果中,没有得到我想要的数据。

接口调用

  配置好API请求后,开始调用,但是在返回结果中,没有得到正确的数据。
返回结果

原因分析:,可能是POST未接收到正确的参数,为验证这一结果,在控制台查看服务运行情况。

image.png

控制台果然没有打印接收到POST参数,这里就分析可能是HEADERS的问题。

image.png


查阅资料:
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"属性;


再比如导师写的某接口文档里说明里的
image.png


以及在本门课程学习中遇到的

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
Content-Type为application/x-www-form-urlencoded
控制台打印


问题依然没有解决,这时候经过了很长时间的调试,然后我认为可能是参数的问题,经过反复尝试,终于发现了问题。

发现问题

这里还有个form,可以用来添加参数,我就试了一下
获取数据成功

问题总结

  该问题的产生是自己对接口调试的不熟悉产生的,那么为什么使用POST请求时将参数填写在上面的位置不可以,但是填写在body位置可以,或者说为什么GET请求可以,POST会出现问题呢?

答:Params处设置的变量请求时会将参数放在url后通过?传参(有点像GET方法传参数),而Body里设置的参数则是接口真正请求时发的参数。