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

jma*_*mac 30 iphone json httprequest ios

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

  1. 路线:{url}/{app_name/{controller}/{action}
  2. 控制器和动作应该是小型的.
  3. API测试链接:http:****************
  4. 请求应使用POST方法.
  5. 参数应通过请求内容主体(FormUrlEncodedContent)传递.
  6. 参数应为json格式.
  7. 参数是关键敏感的.

在协议中没有第5号经验,我搜索并以我的代码结束.

-(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];
        }

    }];

}
Run Code Online (Sandbox Code Playgroud)

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

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

我错过了什么?

Dar*_*iya 44

尝试这样的代码

目标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];
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

我希望这段代码对你有用.

  • Swift 3代码示例错误.它根本没有执行application/x-www-form-urlencoded,它正在发送JSON. (6认同)

Man*_*dan 12

斯威夫特 4

let params = ["password":873311,"username":"jadon","client_id":"a793fb82-c978-11e9-a32f-2a2ae2dbcce4"]
let jsonString = params.reduce("") { "\($0)\($1.0)=\($1.1)&" }.dropLast()
let jsonData = jsonString.data(using: .utf8, allowLossyConversion: false)!
urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
urlRequest.httpBody  = jsonData 
Run Code Online (Sandbox Code Playgroud)


Mua*_*arl 8

@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
Run Code Online (Sandbox Code Playgroud)

以上代码在我的情况下工作正常.


Jef*_*ier 7

Swift 确实提供了 URL-%-encoding 的函数,但它与 @nolanw 在第一条评论中指出的并不完全匹配。对于原始问题中的步骤 5,一旦您拥有某种结构中的键值对,这里有一个简短的编码替代方案(Swift 4.2):

var urlParser = URLComponents()
urlParser.queryItems = [
    URLQueryItem(name: "name", value: "Tim Tebow"),
    URLQueryItem(name: "desc", value: "Gators' QB")
]
let httpBodyString = urlParser.percentEncodedQuery
Run Code Online (Sandbox Code Playgroud)

将其粘贴到 Xcode Playground 中,然后添加print(httpBodyString!). 在输出中,您将看到:

name=Tim%20Tebow&desc=Gators'%20QB
Run Code Online (Sandbox Code Playgroud)

注意:这是针对基本形式值的百分比编码集(即不是二进制数据也不是多部分)

  • 这是一个好主意,但并不完全符合 [application/x-www-form-urlencoded` 序列化规范](https://url.spec.whatwg.org/#urlencoded-serializing);空格应编码为“+”,但使用“URLComponents.percentEncodedQuery”时,空格会编码为“%20”。这可能对您的用例没有影响,但我认为值得指出,以防它影响其他人的用例! (4认同)

Zme*_*mey 5

此版本处理参数编码并用“+”替换空格。

extension String {
    static let formUrlencodedAllowedCharacters =
        CharacterSet(charactersIn: "0123456789" +
            "abcdefghijklmnopqrstuvwxyz" +
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
            "-._* ")

    public func formUrlencoded() -> String {
        let encoded = addingPercentEncoding(withAllowedCharacters: String.formUrlencodedAllowedCharacters)
        return encoded?.replacingOccurrences(of: " ", with: "+") ?? ""
    }
}

class HTTPUtils {
    public class func formUrlencode(_ values: [String: String]) -> String {
        return values.map { key, value in
            return "\(key.formUrlencoded())=\(value.formUrlencoded())"
        }.joined(separator: "&")
    }
}

let headers = [
    "content-type": "application/x-www-form-urlencoded; charset=utf-8"
]

let body = HTTPUtils.formUrlencode([
    "field": "value"
])

var request = try URLRequest(url: url, method: .post, headers: headers)
request.httpBody = body.data(using: .utf8)

URLSession.shared.dataTask(with: request, completionHandler: { ... }).resume()
Run Code Online (Sandbox Code Playgroud)