11

我嘗試從服務器獲取數據。我使用NSURLConnectionDataDelegate,NSURLConnectionDelegate。有代碼(Objective - C)。HTTP狀態碼411 - 所需長度

-(void)sendRequest 
{ 
NSURL* url = [[NSURL alloc] initWithString:@"http://SomeServer"]; 

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init]; 


NSString* reqBody = [NSString stringWithFormat:@"<tag>Content</tag>"]; 

NSData* reqData = [reqBody dataUsingEncoding:NSUTF8StringEncoding]; 

NSInputStream* stream = [NSInputStream inputStreamWithData:reqData]; 



[request setURL:url]; 
[request setHTTPBodyStream:stream]; 
[request setHTTPMethod:@"POST"]; 

self.wpData = [[NSMutableData alloc] init]; 
NSURLConnection* conection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

[conection start]; 

} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 

    [self.wpData setLength:0];  

} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d { 
NSString* str = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding]; 

NSLog(@"RESPONSE DATA: %@",str); 
[self.wpData appendData:d]; 
} 

,但我得到 「411 - 需要的長度」 當我用

[request setHTTPBodyStream:stream]; 

和 「HASH(someAddress)」 當我使用

[request setHTTPBody:reqData]; 

我試圖

[request setHTTPBodyStream:stream]; 
NSString *postLength = [NSString stringWithFormat:@"%d", [reqData length]]; 
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 

但又是「HASH(someAdddress)」

我做錯了什麼? 對不起,我的英文。謝謝:)

回答

17

我做錯了什麼?

什麼都沒有。

服務器發送HTTP狀態碼411(長度要求)作爲響應,當它拒絕接受沒有內容長度標頭的消息時,無論出於何種原因。

服務器只是可能接受或不接受沒有內容長度標頭的內容。

當您通過屬性HTTPBodyStream爲請求設置NSInputStream對象爲請求正文時,NSURLConnection無法再評估正文本身的長度。 (對於一個流沒有屬性length)。因此,NSURLConnection使用某種「傳輸模式」,即「分塊傳輸編碼」。這種傳輸模式應該成功傳輸任何機構,它不需要Content-Legth頭(實際上必須不包含一個)。唉,服務器根本不接受這種類型的傳輸。

另見:Chunked transfer encoding(wiki)。

爲了解決該問題在客戶端:

  • 確定身體自己的長度(如果可能的話),並設置一個「內容長度」報頭字段的請求。如果此輸入流是從文件或NSData對象創建的,則可以輕鬆確定長度。但一定要設置與實際流內容的字節完全相同的長度。

  • 不要使用NSInputStream,但使用NSData對象的身體和通過屬性HTTPBody設置。當您將主體設置爲NSData對象時,NSURLConnection可以自己確定內容長度,並且會自動添加正確長度的Content-Length標頭,除非您自己將其設置在請求中。