当我尝试向我的服务器上的API发送POST请求时,我遇到了一个问题,我已经遵循了许多不同的教程,但它仍然无法正常工作.我知道我的问题与POST请求有关但我无法解决!所以这是我在Swift中的代码和我在PHP中的API :(是的,我已经用代码中的真实ID替换了xxxx)
总结服务器接收请求,例如,如果我手动输入伪工作,它真的是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()*/
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
先谢谢:)
Rob*_*Rob 15
正如其他人所指出的那样,请求的编码并不完全正确.你的服务器代码不期待JSON请求,而是使用$_POST变量(这意味着该请求应该具有Content-Type的application/x-www-form-urlencoded).这就是你应该创造的东西.例如在Swift 3及更高版本中:
var request = URLRequest(url: url)
request.httpMethod = "POST"
let parameters = ["somekey" : "valueforkey"]
request.setContent(with: parameters)
let task = session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
// your response parsing code here
}
task.resume()
Run Code Online (Sandbox Code Playgroud)
该setContent方法将采用表单的字典["key1": "foo", "key2" : "bar"]并httpBody使用看起来像的东西填充key1=foo&key2=bar.如果这样做,服务器将能够解析$_POST请求.
extension URLRequest {
/// Set body and header for x-www-form-urlencoded request
///
/// - Parameter parameters: Simple string dictionary of parameters to be encoded in body of request
mutating func setContent(with parameters: [String: String]) {
setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let array = parameters.map { entry -> String in
let key = entry.key.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)!
let value = entry.value.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)!
return key + "=" + value
}
httpBody = array.joined(separator: "&").data(using: .utf8)!
}
}
Run Code Online (Sandbox Code Playgroud)
注意,这也对值进行了百分比编码(并且,以防万一),这也很关键.而另一些人建议使用addingPercentEncoding与.urlQueryAllowed可悲的是不会做的工作,因为这会让某些保留字符(特别是+)通过转义.大多数Web服务将解释+为一个空间,在与一致性的x-www-form-urlencoded规范.因此,采用Alamofire采用的方法,我定义了一个字符集,它将使用各种分隔符对值进行编码:
extension CharacterSet {
/// Returns the character set for characters allowed in the individual parameters within a query URL component.
///
/// The query component of a URL is the component immediately following a question mark (?).
/// For example, in the URL `http://www.example.com/index.php?key1=value1#jumpLink`, the query
/// component is `key1=value1`. The individual parameters of that query would be the key `key1`
/// and its associated value `value1`.
///
/// According to RFC 3986, the set of unreserved characters includes
///
/// `ALPHA / DIGIT / "-" / "." / "_" / "~"`
///
/// In section 3.4 of the RFC, it further recommends adding `/` and `?` to the list of unescaped characters
/// for the sake of compatibility with some erroneous implementations, so this routine also allows those
/// to pass unescaped.
static var urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)
return allowed
}()
}
Run Code Online (Sandbox Code Playgroud)
对于Swift 2的演绎,请参阅此答案的上一版本.
nat*_*edo 11
试试这个:
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()
Run Code Online (Sandbox Code Playgroud)
您必须使用UTF8字符串编码对数据进行编码.如果需要为请求正文设置多个字段和值对,则可以更改正文字符串,例如"pseudo = test&language = swift".实际上,我通常会为NSMutableURLRequest创建一个扩展,并添加一个方法,该方法将字典作为参数,并使用正确的编码将此地图(字典)的内容设置为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)
}
}
Run Code Online (Sandbox Code Playgroud)
你可以用它作为:
request.setBodyContent(params)
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助你!
| 归档时间: |
|
| 查看次数: |
7906 次 |
| 最近记录: |