POST和SWIFT和API

当我尝试向我的服务器上的API发送POST请求时遇到了问题,我遵循许多不同的教程,但仍然无效。 我知道比我的问题是与POST请求,但我不能解决它! 所以这是我在Swift中的代码和我在PHP中的API :(是的,我已经用我的代码中的真实IDreplace了xxxx)

总结服务器接收请求,例如,如果我手动input一个伪它工作,这真的是POST方法谁不工作。服务器没有收到POST参数

SWIFT代码 :

var request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/academy/test.php")!) var session = NSURLSession.sharedSession() request.HTTPMethod = "POST" var params = ["pseudo":"test"] as Dictionary<String, String> var err: NSError? request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err) request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in println("Response: \(response)") var strData = NSString(data: data, encoding: NSUTF8StringEncoding) println("Body: \(strData)") var err: NSError? var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary // Did the JSONObjectWithData constructor return an error? If so, log the error to the console if(err != nil) { println(err!.localizedDescription) let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) println("Error could not parse JSON: '\(jsonStr)'") } else { // The JSONObjectWithData constructor didn't return an error. But, we should still // check and make sure that json has a value using optional binding. if let parseJSON = json { // Okay, the parsedJSON is here, let's get the value for 'success' out of it var success = parseJSON["success"] as? Int println("Succes: \(success)") } else { // Woa, okay the json object was nil, something went worng. Maybe the server isn't running? let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) println("Error could not parse JSON: \(jsonStr)") } } }) task.resume()*/ 

PHP代码:

 $BDD_hote = 'xxxxx'; $BDD_bd = 'xxxxx'; $BDD_utilisateur = 'xxxxx'; $BDD_mot_passe = 'xxxxx'; try{ $bdd = new PDO('mysql:host='.$BDD_hote.';dbname='.$BDD_bd, $BDD_utilisateur, $BDD_mot_passe); $bdd->exec("SET CHARACTER SET utf8"); $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch(PDOException $e){ echo 'Erreur : '.$e->getMessage(); echo 'N° : '.$e->getCode(); } $pseudo = addslashes($_POST["pseudo"]); $req = $bdd->query("SELECT * from users WHERE pseudo='$pseudo'"); $resultArray = array(); $donnees = $req->fetch(); echo json_encode($donnees); 

感谢预先:)

尝试这个:

  let myURL = NSURL(string: "http://localhost:8888/academy/test.php")! let request = NSMutableURLRequest(URL: myURL) request.HTTPMethod = "POST" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept") let bodyStr:String = "pseudo=test" request.HTTPBody = bodyStr.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in // Your completion handler code here } task.resume() 

你必须使用UTF8string编码来编码你的数据。 如果您需要为请求主体设置多个字段和值对,则可以更改主体string,例如“pseudo = test&language = swift”。 实际上,我通常为NSMutableURLRequest创build一个扩展,并添加一个以字典为参数的方法,并使用正确的编码将此地图(字典)的内容设置为HTTPBody。 这可能对你有用:

  extension NSMutableURLRequest { func setBodyContent(contentMap: Dictionary<String, String>) { var firstOneAdded = false let contentKeys:Array<String> = Array(contentMap.keys) for contentKey in contentKeys { if(!firstOneAdded) { contentBodyAsString += contentKey + "=" + contentMap[contentKey]! firstOneAdded = true } else { contentBodyAsString += "&" + contentKey + "=" + contentMap[contentKey]! } } contentBodyAsString = contentBodyAsString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! self.HTTPBody = contentBodyAsString.dataUsingEncoding(NSUTF8StringEncoding) } } 

你可以使用这个:

 request.setBodyContent(params) 

我希望这可以帮助你!

正如其他人所指出的那样,请求的编码并不完全正确。 您的服务器代码不期待JSON请求,而是使用$_POSTvariables(这意味着该请求应具有application/x-www-form-urlencoded Content-Type application/x-www-form-urlencoded )。 所以这就是你应该创造的。 在Swift 3:

 var request = URLRequest(url: url) request.httpMethod = "POST" let parameters = ["somekey" : "valueforkey"] request.setBodyContent(parameters) request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") let task = session.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { print("\(error?.localizedDescription ?? "Unknown error")") return } // your response parsing code here } task.resume() 

setBodyContent方法将采用forms为["key1": "foo", "key2" : "bar"]HTTPBody ,并使用类似key1=foo&key2=bar东西填充HTTPBody 。 如果你这样做,服务器将能够parsing请求中的$_POST

 extension URLRequest { /// Populate the HTTPBody of `application/x-www-form-urlencoded` request /// /// - parameter parameters: A dictionary of keys and values to be added to the request mutating func setBodyContent(_ parameters: [String : String]) { let parameterArray = parameters.map { (key, value) -> String in return "\(key.addingPercentEncodingForQuery()!)=\(value.addingPercentEncodingForQuery()!)" } httpBody = parameterArray.joined(separator: "&").data(using: .utf8) } } 

请注意,这也是百分比编码的值,这是至关重要的。 而另外一些人build议使用加addingPercentEncoding ,遗憾的是不会做这项工作,因为它会让某些保留的字符通过非转义。 值得注意的是,在不太可能的情况下,请求参数字典的值包含一个&或者+字符,它会让它们通过未转义的(而&不正确地被解释为终止该值,而+将被解释为空格)。 所以你必须做自己的百分比逃避,以确保只有狭义的毫无保留的字符集被留下。 你可以做这样的事情:

 extension String { /// Percent escape value to be added to a HTTP request /// /// This percent-escapes all characters besides the alphanumeric character set and "-", ".", "_", and "*". /// This will also replace spaces with the "+" character as outlined in the application/x-www-form-urlencoded spec: /// /// http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm /// /// - returns: Return percent escaped string. func addingPercentEncodingForQuery() -> String? { let allowed = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._* ") return addingPercentEncoding(withAllowedCharacters: allowed)?.replacingOccurrences(of: " ", with: "+") } } 

或者,您可以通过以.urlQueryAllowed开头构build允许字符的字符集,但是您仍然需要删除一些字符,否则会允许某些字符通过未转义(例如+ )。 请参阅https://stackoverflow.com/a/35912606/1271826

Swift 2翻译,请参阅此答案的以前的修订 。

下面的PHP代码是用于接收application/url+encode编码后的消息。 请参阅https://en.wikipedia.org/wiki/Percent-encoding

 $_POST["pseudo"] 

而你的swift代码是发送一个JSON编码的string数据。 他们是不相容的。

如果您不想更改php代码,请在Swift中发送url编码格式消息li:

//更新了@Rob的更正

  var params = ["param1":"value1", "papam2": "value 2"] var body = "" for (key, value) in params { body = body.stringByAppendingString(key) body = body.stringByAppendingString("=") body = body.stringByAppendingString(value.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!) body = body.stringByAppendingString("&") } body = body.substringToIndex(advance(body.startIndex, countElements(body)-1)) // remove the last "&" request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)