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

Getting bad request error with alamofire JSON request

我一直在转换这个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";
    }
);

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

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)

你有一个有效的 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”headers不应该这不是问题。
尝试不带 -L 参数的命令可能会检查它是否“重要”(如果它是 --location)。
然后,不同之处在于 data 参数 (-d)。一个是JSON,另一个是URL编码。

然后,让我们看看你的代码,URLEncoding(destination: .httpBody) 可能是罪魁祸首。使用 JSONEncoding.default 会起作用。

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

你在那里说你将按照 JSON 协议在 body 中提供参数。

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

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

URLEncoding(destination: .httpBody)

没有道理,对吧?你在自相矛盾。