Swift调用Nordigen API设POST仍返回GET不允许错误求助
我尝试通过Nordigen API获取token,尽管在Swift代码中设置httpMethod为"POST",但始终收到405错误,提示:"Method "GET" not allowed"。我是Swift新手,推测遗漏了基础设置。
我的Swift代码如下:
import Foundation let apiUrl = URL(string: "https://ob.nordigen.com/api/v2/token/new")! let clientId = "your_client_id" let clientSecret = "your_client_secret" let requestBody: [String: Any] = [ "client_id": clientId, "client_secret": clientSecret ] let requestData = try! JSONSerialization.data(withJSONObject: requestBody) var request = URLRequest(url: apiUrl) request.httpMethod = "POST" request.httpBody = requestData request.setValue("application/json", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request) { (data, response, error) in if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { print(json) if let accessToken = json["access"] as? String { print("Access Token: \(accessToken)") } } } task.resume()
按此代码执行,即便没有有效client id/secret,理应返回401错误“Authentication failed”,提示“ No active account found with the given credentials”。我用JavaScript测试该API可正常工作,代码如下:
var userid = "user id"; var userkey = "user key"; var raw = JSON.stringify({"secret_id":userid,"secret_key":userkey}); var myHeaders = {"accept": "application/json", "Content-Type": "application/json"} var requestOptions = { 'method': 'POST', 'headers': myHeaders, 'payload': raw }; var response = UrlFetchApp.fetch("https://ob.nordigen.com/api/v2/token/new/", requestOptions); var json = response.getContentText(); token = JSON.parse(json).access;
问题原因及解决步骤
URL末尾缺少斜杠导致重定向:Swift代码中使用的URL是
https://ob.nordigen.com/api/v2/token/new,而JS代码里的URL带末尾斜杠/。部分API服务器会对不带斜杠的路径返回301重定向,重定向过程中POST请求会被自动转为GET请求,从而触发Method "GET" not allowed的405错误。
解决:将Swift中的URL改为带末尾斜杠的版本:let apiUrl = URL(string: "https://ob.nordigen.com/api/v2/token/new/")!请求体参数名错误:对比JS代码可以看到,Nordigen API要求的参数名是
secret_id和secret_key,但Swift代码中用了client_id和client_secret,这会导致后续即使解决了405问题,也会返回401认证失败。
解决:修正请求体的参数名:let requestBody: [String: Any] = [ "secret_id": clientId, "secret_key": clientSecret ]避免强制解包崩溃:代码中使用
try!会在JSON序列化失败时直接崩溃,建议用do-catch处理错误:do { let requestData = try JSONSerialization.data(withJSONObject: requestBody) // 后续请求设置代码 } catch { print("JSON序列化失败:\(error)") }
调整后的完整Swift代码如下:
import Foundation guard let apiUrl = URL(string: "https://ob.nordigen.com/api/v2/token/new/") else { print("无效的API URL") exit(1) } let secretId = "your_secret_id" let secretKey = "your_secret_key" let requestBody: [String: Any] = [ "secret_id": secretId, "secret_key": secretKey ] do { let requestData = try JSONSerialization.data(withJSONObject: requestBody) var request = URLRequest(url: apiUrl) request.httpMethod = "POST" request.httpBody = requestData request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept") let task = URLSession.shared.dataTask(with: request) { (data, response, error) in if let error = error { print("请求错误:\(error)") return } guard let httpResponse = response as? HTTPURLResponse else { print("无效的响应") return } print("响应状态码:\(httpResponse.statusCode)") if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed) as? [String: Any] { print("响应JSON:\(json)") if let accessToken = json["access"] as? String { print("获取到Access Token: \(accessToken)") } } } task.resume() } catch { print("JSON序列化失败:\(error)") }
内容的提问来源于stack exchange,提问作者Pospa

