Nối dữ liệu vào một POST NSURLRequest


83

Làm cách nào để bạn nối dữ liệu vào một dữ liệu hiện có POST NSURLRequest? Tôi cần thêm một tham số mới userId=2323.


3
Vui lòng mô tả câu hỏi của bạn với một số mã.
Tirth

Câu trả lời:


192

Nếu bạn không muốn sử dụng các lớp của bên thứ 3 thì sau đây là cách bạn đặt nội dung bài đăng ...

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                     timeoutInterval:60.0];

[request setHTTPMethod:@"POST"];
NSString *postString = @"company=Locassa&quality=AWESOME!";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request 
                                                             delegate:self];

Chỉ cần thêm cặp khóa / giá trị của bạn vào chuỗi bài đăng


2
Tôi cần thêm tham số mới vào NSURLRequest hiện có, không phải tạo một yêu cầu mới. Tôi tin rằng nó phải được chuyển đổi thành NSMutableURLRequest trước. Điều tôi không biết là làm thế nào để lấy dữ liệu POST hiện có.
Tim

1
Nói cách khác là làm cách nào để bạn có được chuỗi đăng của một yêu cầu hiện có?
Tim

1
Bạn có thể truy cập - (NSData *) HTTPBody mà bạn có thể mã hóa thành một NSString, các cặp khóa / giá trị
Simon Lee

Dữ liệu bài đăng hiện có được mã hóa bằng UTF8 như trong ví dụ của bạn. Làm cách nào để đảo ngược mã hóa? Sau đó, tạo một chuỗi mới với các tham số mới? sau đó mã hóa dữ liệu bài đăng mới
Tim

1
Điều này sẽ hoạt động nhưng tôi không thể kiểm tra nó vào lúc này .... NSMutableString * currentPost = [[NSMutableString Distribution] initWithData: [req HTTPBody] encoding: NSUTF8StringEncoding]; [currentPost appendFormat: @ "&% @ =% @", @ "name", @ "Locassa"];
Simon Lee

16

Tất cả các thay đổi đối với NSMutableURLRequestphải được thực hiện trước khi gọi NSURLConnection.

Tôi gặp sự cố này khi tôi sao chép và dán mã ở trên và chạy TCPMonvà thấy yêu cầu GETthay vì mong đợi POST.

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                     cachePolicy:NSURLRequestUseProtocolCachePolicy
                                 timeoutInterval:60.0];


[request setHTTPMethod:@"POST"];
NSString *postString = @"company=Locassa&quality=AWESOME!";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request 
                                                         delegate:self];

12

Các bài viết trước đây về việc hình thành POSTyêu cầu phần lớn là đúng (thêm các tham số vào phần nội dung, không phải URL). Nhưng nếu có bất kỳ khả năng dữ liệu đầu vào nào chứa bất kỳ ký tự dành riêng nào (ví dụ: dấu cách, dấu và, dấu cộng), thì bạn sẽ muốn xử lý các ký tự dành riêng này. Cụ thể, bạn nên thoát phần trăm đầu vào.

//create body of the request

NSString *userid = ...
NSString *encodedUserid = [self percentEscapeString:userid];
NSString *postString    = [NSString stringWithFormat:@"userid=%@", encodedUserid];
NSData   *postBody      = [postString dataUsingEncoding:NSUTF8StringEncoding];

//initialize a request from url

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:postBody];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

//initialize a connection from request, any way you want to, e.g.

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Trong đó precentEscapeStringphương thức được định nghĩa như sau:

- (NSString *)percentEscapeString:(NSString *)string
{
    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)string,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

Lưu ý, có một NSStringphương pháp đầy hứa hẹn , stringByAddingPercentEscapesUsingEncoding(hiện không được dùng nữa), thực hiện điều gì đó rất tương tự, nhưng hãy chống lại sự cám dỗ để sử dụng nó. Nó xử lý một số ký tự (ví dụ: ký tự khoảng trắng), nhưng không xử lý một số ký tự khác (ví dụ: +hoặc các &ký tự).

Tương đương đương đại stringByAddingPercentEncodingWithAllowedCharacters, nhưng, một lần nữa, đừng bị cám dỗ để sử dụng URLQueryAllowedCharacterSet, vì điều đó cũng cho phép +&vượt qua không thoát. Hai ký tự đó được cho phép trong "truy vấn" rộng hơn, nhưng nếu những ký tự đó xuất hiện trong một giá trị trong một truy vấn, chúng phải thoát. Về mặt kỹ thuật, bạn có thể sử dụng URLQueryAllowedCharacterSetđể xây dựng một bộ ký tự có thể thay đổi và loại bỏ một vài ký tự mà họ đã đưa vào đó hoặc xây dựng bộ ký tự của riêng bạn từ đầu.

Ví dụ, nếu bạn nhìn vào Alamofire của mã hóa tham số , họ mất URLQueryAllowedCharacterSetvà sau đó loại bỏ generalDelimitersToEncode(trong đó bao gồm các nhân vật #, [, ], và @, nhưng vì một lỗi lịch sử trong một số máy chủ web cũ, không phải ?và cũng không /) và subDelimitersToEncode(tức là !, $, &, ', (, ), *, +, ,, ;, và =). Đây là cách triển khai đúng (mặc dù bạn có thể tranh luận về việc loại bỏ ?/), mặc dù khá phức tạp. Có lẽ CFURLCreateStringByAddingPercentEscapeslà trực tiếp / hiệu quả hơn.


Đúng về stringByAddingPercentEscapesUsingEncoding:, nhưng stringByAddingPercentEncodingWithAllowedCharacters:hoạt động tốt với mọi nhân vật. Ví dụ: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Alejandro Cotilla

@AlejandroDavidCotillaRojas - Bạn có thể sử dụng stringByAddingPercentEncodingWithAllowedCharacters, nhưng không thể sử dụng URLQueryAllowedCharacterSet, vì điều đó bao gồm +&(đó là những ký tự được phép trong truy vấn rộng hơn, nhưng nếu những ký tự đó xuất hiện trong một giá trị trong một truy vấn, chúng phải thoát ra, điều mà bộ ký tự đó sẽ không thực hiện ). Vì vậy, bạn có thể sử dụng URLQueryAllowedCharacterSetđể xây dựng một bộ ký tự có thể thay đổi và xóa một vài ký tự mà họ đã đưa vào đó hoặc xây dựng bộ ký tự của riêng bạn từ đầu. Hoặc sử dụng CFURLCreateStringByAddingPercentEscapes.
Rob

Câu trả lời tuyệt vời, thực sự phù hợp với việc sử dụng Alamofire để tránh tất cả những điều này!
Dan Rosenstark

Do tính năng CFURLCreateStringByAddingPercentEscapesnày hiện không được dùng nữa, bạn thực sự nên tự mình xây dựng bộ ký tự phù hợp. Xem stackoverflow.com/a/54742187/1271826 .
Rob

8
 NSURL *url= [NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                                        cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                    timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
 NSString *postString = @"userId=2323";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

8

Đoạn mã ví dụ trên thực sự hữu ích đối với tôi, tuy nhiên (như đã được gợi ý ở trên), tôi nghĩ bạn cần sử dụng NSMutableURLRequesthơn là sử dụng NSURLRequest. Ở dạng hiện tại, tôi không thể làm cho nó phản hồi setHTTPMethodcuộc gọi. Thay đổi kiểu đã khắc phục mọi thứ.


1

Bất kỳ ai đang tìm kiếm một giải pháp nhanh chóng

let url = NSURL(string: "http://www.apple.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPBody = "company=Locassa&quality=AWESOME!".dataUsingEncoding(NSUTF8StringEncoding)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.