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
.
Câu trả lời:
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
Tất cả các thay đổi đối với NSMutableURLRequest
phả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 TCPMon
và thấy yêu cầu GET
thay 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];
Các bài viết trước đây về việc hình thành POST
yê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 đó precentEscapeString
phươ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 NSString
phươ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à &
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 URLQueryAllowedCharacterSet
và 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ỏ ?
và /
), mặc dù khá phức tạp. Có lẽ CFURLCreateStringByAddingPercentEscapes
là trực tiếp / hiệu quả hơn.
stringByAddingPercentEscapesUsingEncoding:
, nhưng stringByAddingPercentEncodingWithAllowedCharacters:
hoạt động tốt với mọi nhân vật. Ví dụ: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
stringByAddingPercentEncodingWithAllowedCharacters
, nhưng không thể sử dụng URLQueryAllowedCharacterSet
, vì điều đó bao gồm +
và &
(đó 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
.
CFURLCreateStringByAddingPercentEscapes
nà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 .
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]];
Đ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 NSMutableURLRequest
hơ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 setHTTPMethod
cuộc gọi. Thay đổi kiểu đã khắc phục mọi thứ.
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)