POST请求使用application / x-www-form-urlencoded

后端开发人员在POST请求中给出了这些指示信息:

  1. 路线:{url} / {app_name / {controller} / {action}
  2. 控制器和行动应该在小型大写字母上。
  3. APItesting链接:http: * ** * ** * ** * ** * ***
  4. 请求应该使用POST方法。
  5. 参数应该通过请求内容体(FormUrlEncodedContent)传递。
  6. 参数应该是json格式。
  7. 参数是关键敏感的。

在协议中没有5号的经验,我search了,并以我的代码结束。

-(id)initWithURLString:(NSString *)URLString withHTTPMEthod:(NSString *)method withHTTPBody:(NSDictionary *)body { _URLString = URLString; HTTPMethod = method; HTTPBody = body; //set error message errorMessage = @"Can't connect to server at this moment. Try again later"; errorTitle = @"Connection Error"; return self; } -(void)fireConnectionRequest { NSOperationQueue *mainQueue = [[NSOperationQueue alloc] init]; [mainQueue setMaxConcurrentOperationCount:5]; NSError *error = Nil; NSURL *url = [NSURL URLWithString:_URLString]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; NSData *sendData = [NSJSONSerialization dataWithJSONObject:HTTPBody options:NSJSONWritingPrettyPrinted error:&error]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setHTTPBody: sendData]; [NSURLConnection connectionWithRequest:request delegate:self]; NSString *jsonString = [[NSString alloc]initWithData:sendData encoding:NSUTF8StringEncoding]; //fire URL connectiion request [NSURLConnection sendAsynchronousRequest:request queue:mainQueue completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error) { //get the return message and transform to dictionary NSString *data = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; returnMessage = [NSJSONSerialization JSONObjectWithData: [data dataUsingEncoding:NSUTF8StringEncoding] options: NSJSONReadingMutableContainers error:&error]; //check return message if (!error) { [delegate returnMessageForTag:self.tag]; } else { [delegate returnErrorMessageForTag:self.tag]; } }]; } 

我传递格式化为JSON的字典。 他同意我能够传递正确的数据。 我能够连接到API,但是当我尝试发送数据进行注册时,它总是返回“FAILED”。 连接没有问题,但我没有传输数据。

在这里使用相同的API的android开发人员没有问题,但由于他不熟悉iOS,无法帮助我。

我错过了什么?

尝试像这样的代码

目标C

  NSString *post =[NSString stringWithFormat:@"AgencyId=1&UserId=1&Type=1&Date=%@&Time=%@&Coords=%@&Image=h32979`7~U@)01123737373773&SeverityLevel=2",strDateLocal,strDateTime,dict]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]]; NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://google/places"]]]; [request setHTTPMethod:@"POST"]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; NSError *error; NSURLResponse *response; NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSString *str=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding]; 

Swift 2.2

 var post = "AgencyId=1&UserId=1&Type=1&Date=\(strDateLocal)&Time=\(strDateTime)&Coords=\(dict)&Image=h32979`7~U@)01123737373773&SeverityLevel=2" var postData = post.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)! var postLength = "\(postData.length)" var request = NSMutableURLRequest() request.URL = NSURL(string: "http://google/places")! request.HTTPMethod = "POST" request.setValue(postLength, forHTTPHeaderField: "Content-Length") request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.HTTPBody = postData NSError * error NSURLResponse * response var urlData = try! NSURLConnection.sendSynchronousRequest(request, returningResponse: response)! var str = String(data: urlData, encoding: NSUTF8StringEncoding) 

Swift 3.0

 let jsonData = try? JSONSerialization.data(withJSONObject: kParameters) let url: URL = URL(string: "Add Your API URL HERE")! print(url) var request: URLRequest = URLRequest(url: url) request.httpMethod = "POST" request.httpBody = jsonData request.setValue(Constant.UserDefaults.object(forKey: "Authorization") as! String?, forHTTPHeaderField: "Authorization") request.setValue(Constant.kAppContentType, forHTTPHeaderField: "Content-Type") request.setValue(Constant.UserAgentFormat(), forHTTPHeaderField: "User-Agent") let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in if data != nil { do { let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary print(json) } catch let error as NSError { print(error) } } else { let emptyDict = NSDictionary() } }) task.resume() 

我希望这个代码对你有用。

@fatihyildizhan

没有足够的声誉来直接评论你的答案,所以这个答案。

Swift 1.2

 let myParams = "username=user1&password=12345" let postData = myParams.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true) let postLength = String(format: "%d", postData!.length) var myRequest = NSMutableURLRequest(URL: self.url) myRequest.HTTPMethod = "POST" myRequest.setValue(postLength, forHTTPHeaderField: "Content-Length") myRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") myRequest.HTTPBody = postData var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil 

上面的代码在我的情况下工作正常。

有可能将此代码转换为swift吗? 我已经尝试,但无法处理。 也许这个代码块可能会帮助你。 谢谢。

 let myParams:NSString = "username=user1&password=12345" let myParamsNSData:NSData = NSData(base64EncodedString: myParams, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)! let myParamsLength:NSString = NSString(UTF8String: myParamsNSData.length) let myRequest: NSMutableURLRequest = NSURL(fileURLWithPath: self.url) myRequest.HTTPMethod = "POST" myRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") myRequest.HTTPBody = myParamsNSData var data2: NSData! var error2: NSError! 

用Swift 3,让jsonData =试试? JSONSerialization.data(withJSONObject:kParameters)不能正常工作,所以我不得不复制AlamoFire解决scheme…

 let body2 = ["username": "au@gmail.com", "password": "111", "client_secret":"7E", "grant_type":"password"] let data : Data = query(body2).data(using: .utf8, allowLossyConversion: false)!var request : URLRequest = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type"); request.setValue(NSLocalizedString("lang", comment: ""), forHTTPHeaderField:"Accept-Language"); request.httpBody = data do {...} } public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] { var components: [(String, String)] = [] if let dictionary = value as? [String: Any] { for (nestedKey, value) in dictionary { components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value) } } else if let array = value as? [Any] { for value in array { components += queryComponents(fromKey: "\(key)[]", value: value) } } else if let value = value as? NSNumber { if value.isBool { components.append((escape(key), escape((value.boolValue ? "1" : "0")))) } else { components.append((escape(key), escape("\(value)"))) } } else if let bool = value as? Bool { components.append((escape(key), escape((bool ? "1" : "0")))) } else { components.append((escape(key), escape("\(value)"))) } return components } public func escape(_ string: String) -> String { let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 let subDelimitersToEncode = "!$&'()*+,;=" var allowedCharacterSet = CharacterSet.urlQueryAllowed allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") var escaped = "" if #available(iOS 8.3, *) { escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string } else { let batchSize = 50 var index = string.startIndex while index != string.endIndex { let startIndex = index let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex let range = startIndex..<endIndex let substring = string.substring(with: range) escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? substring index = endIndex } } return escaped } 

还有一个扩展:

 extension NSNumber { fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }} 

这是暂时的,它必须是一个更好的解决scheme…

希望它有帮助…

 let params:[String: Any] if "application/x-www-form-urlencoded" { let bodyData = params.stringFromHttpParameters() self.request.httpBody = bodyData.data(using: String.Encoding.utf8)} if "application/json"{ do { self.request.httpBody = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions()) } catch { print("bad things happened") } } 

扩展词典

 func stringFromHttpParameters() -> String { let parameterArray = self.map { (key, value) -> String in let percentEscapedKey = (key as!String).stringByAddingPercentEncodingForURLQueryValue()! let percentEscapedValue = (value as! String).stringByAddingPercentEncodingForURLQueryValue()!} return "\(percentEscapedKey)=\(percentEscapedValue)"} return parameterArray.joined(separator: "&")}