使用 alamofire JSON 请求出现错误的请求错误

Posted

技术标签:

【中文标题】使用 alamofire JSON 请求出现错误的请求错误【英文标题】:Getting bad request error with alamofire JSON request 【发布时间】:2021-08-31 10:37:53 【问题描述】:

我一直在转换这个 curl 语法

curl -L -X POST 'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \-H 'x-api-key: REPLACE WITH YOUR API KEY' \-H 'Content-Type: application/json' \-d '"registrationNumber": "TE57VRN"'

使用 Alamofire 进入 Swift 并掌握此语法

guard let url = URL(string: "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles") else  return 

                    let headers : HTTPHeaders = [
                            "x-api-key": "mykey",
                            "Content-Type": "application/json"

                        ]

                    let params: Parameters = [
                            "registrationNumber" : "myreg"
                        ]

                    AF.request(url, method: .post, parameters: params, encoding: URLEncoding(destination: .httpBody), headers: headers).responseJSON(completionHandler:  response in
                        print(response)
                    )

但是,我得到了输出

success(
errors =     (
            
        code = ENQ103;
        detail = "Invalid format for field - vehicle registration number";
        status = 400;
        title = "Bad Request";
    
);

请有人解释我做错了什么。谢谢

【问题讨论】:

【参考方案1】:

API 期望参数以 JSON 格式发送,但您以 URL 编码发送。 尝试使用JSONParameterEncoder.default 作为编码器而不是 URL 编码。 检查文档中的使用情况:POST request with JSON Parameters

let parameters: Parameters = [
                            "registrationNumber" : "myreg"
                        ]

AF.request(url, method: .post, parameters: parameters, encoder: JSONParameterEncoder.default)

【讨论】:

尝试 [String: String] 而不是参数【参考方案2】:

你有一个有效的 curl 命令,小(或大)提示:AlamoFire 可以将请求打印为 curl 命令!

在“一步”中:

AF.request(url, method: .post,
           parameters: params,
           encoding: URLEncoding(destination: .httpBody),
           headers: headers)
   .cURLDescription(calling:  curlCommand in
    print("curlCommand1: \(curlCommand)")
).responseJSON(completionHandler:  response in
    print(response)
)

在“两个步骤”中,如果您希望将调用分开而不是全部链接:

let request = AF.request(url, method: .post,
                         parameters: params,
                         encoding: URLEncoding(destination: .httpBody),
                         headers: headers)
request.cURLDescription  curlCommand in
    print("curlCommand2: \(curlCommand)")


request.responseJSON(completionHandler:  response in
    print(response)
)

你应该有输出:

curl -v \
    -X POST \
    -H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
    -H "User-Agent: Alamofired/1.0 (...; build:1; ios 14.5.0) Alamofire/5.4.0" \
    -H "Accept-Language: en;q=1.0, fr-US;q=0.9" \
    -H "Content-Type: application/json" \
    -H "x-api-key: mykey" \
    -d "registrationNumber=myreg" \
    "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles"

现在,如果我们与您的比较:

curl \ 
-L \
-X POST \
'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \
-H 'x-api-key: REPLACE WITH YOUR API KEY' \
-H 'Content-Type: application/json' \
-d '"registrationNumber": "TE57VRN"'

我添加了一些\ 以使其仍然有效...

我们不应该关心顺序,使用 Alamofire 添加的“Accept-Language”、“User-Agent”、“Accept-Encoding”标头应该不是问题。 尝试不带 -L 参数的命令,以检查它是否“重要”(如果是 --location)。 然后,区别在于data 参数(-d)。一个是 JSON,另一个是 URL 编码。

然后,让我们看看你的代码,然后URLEncoding(destination: .httpBody) 可能是罪魁祸首。改用JSONEncoding.default 就可以了。

现在,如果您没有 curl 命令,只需查看您的代码,我就发现了它。如果你考虑一下:

您是说您将按照 JSON 协议在正文中提供参数。

let headers : HTTPHeaders = ["Content-Type": "application/json"]

后来,你使用了 URL 编码协议。

URLEncoding(destination: .httpBody)

没有意义,对吧?你在自相矛盾。

【讨论】:

以上是关于使用 alamofire JSON 请求出现错误的请求错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 读取错误请求的 json 数据(状态码 400)

使用 Alamofire 2.0 请求失败

使用 AlamoFire 发出 HTTP 请求会导致 EXC_BAD_ACCESS

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

Json 解析 Swift 3 Alamofire

使用 Alamofire 序列化 JSON 对象