HTTP Header
協(xié)議頭的字段(Header)阵难,請求(request)或響應(response)。
協(xié)議頭的字段炭序,是以明文的格式傳輸的罚斗,以冒號分隔的鍵名/值對徙鱼,最后以回車(CR)和換行(LF)符序列結尾。協(xié)議頭部分的結束针姿,是以一個空白的字段來標識的袱吆,結果就是,會傳輸兩個連續(xù)的回車換行符對搓幌。 在標準的網絡請求中沒有針對每個協(xié)議頭字段的名字和值的尺寸設置任何限制杆故, 也沒有限制字段的個數。然而 溉愁,出于實際場景及安全性的考慮处铛,大部分的服務器饲趋、客戶端和代理軟件都會實施一些限制。例如撤蟆, 阿帕奇(Apache)2.3 服務器奕塑, 在默認情況下, 會限制每個字段的尺寸不超過 8190字節(jié) 家肯, 同時龄砰,單個請求中最多可以有 100 個協(xié)議頭字段。
1.請求字段(Request)
協(xié)議頭字段 | 說明 | 示例 |
---|---|---|
Accept | 能夠接受的回應內容類型(Content-Types) | Accept: text/plain |
Accept-Charset | 能夠接受的字符集 | Accept-Charset: utf-8 |
Accept-Encoding | 能夠接受的編碼方式列表 | Accept-Encoding:gzip, deflate |
Accept-Language | 能夠接受的回應內容的自然語言列表(Content-Types) | Accept-Language: en-US |
Authorization | 用于超文本傳輸協(xié)議的認證的認證信息 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 用來指定在這次的請求/回復鏈中的所有緩存機制 都必須 遵守的指令 | Cache-Control: no-cache |
Cookie | 之前由服務器通過 Set- Cookie) | Cookie: $Version=1; Skin=new; |
Content-Length | 以 八位字節(jié)數組 (8位的字節(jié))表示的請求體的長度 | Content-Length: 348 |
Content-Type | 請求體的 多媒體類型 (用于POST和PUT請求中) | Content-Type: application/x-www-form-urlencoded |
Range | 僅請求某個實體的一部分讨衣。字節(jié)偏移以0開始换棚。參考 字節(jié)服務 。 | Range: bytes=500-999 |
User-Agent | 瀏覽器的瀏覽器身份標識字符串 | User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0 |
2.Content-Type
- application/x-www-form-urlencoded
數據被編碼為名稱/值對反镇。這是標準的編碼格式固蚤。 - multipart/form-data
數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分歹茶。 - text/plain
數據以純文本形式(text/json/xml/html)進行編碼夕玩,其中不含任何控件或格式字符。
form的enctype屬性為編碼方式惊豺,常用有兩種:application/x-www-form-urlencoded
和multipart/form-data燎孟,默認為application/x-www-form-urlencoded。
- 當action為get時候尸昧,瀏覽器用x-www-form-urlencoded的編碼方式把form數據轉換成一個字串(name1=value1&name2=value2...)揩页,然后把這個字串追加到url后面,用?分割彻磁,加載這個新的url碍沐。當action為pos時候,瀏覽器把form數據封裝到http body中衷蜓,然后發(fā)送到server。 如果沒有type=file的控件尘喝,用默認的application/x-www-form-urlencoded就可以了磁浇。 但是如果有type=file`的話,就要用到multipart/form-data了朽褪。
- 當action為post且Content-Type類型是multipart/form-data置吓,瀏覽器會把整個表單以控件為單位分割,并為每個部分加上Content-Disposition(form-data或者file),Content-Type(默認為text/plain),name(控件name
)等信息缔赠,并加上分割符(boundary)衍锚。
應用場景1
1.2請求地址
https://zkapp.f3322.net:8087
Appid = TaxiManager01
1.3請求方式
通過HTTP的Get、Post方式進行數據請求嗤堰,查詢數據使用Get方式戴质,增加、修改、刪除數據使用Post的方式
1.4返回數據格式說明
返回數據采用以下統(tǒng)一規(guī)范的JSON格式:
{
"Status": "1",
"Message": "登錄成功",
"ErrorCode": "",
"Data": ""
}
本文以下的接口描述的輸出參數是指Data內JSON對象或JSON對象數組的屬性告匠。
1.5客戶端服務接口通訊協(xié)議的安全
1.5.1通訊協(xié)議
本服務端采用安全套接字層超文本傳輸協(xié)議HTTPS戈抄,確保數據傳輸過程安全。
1.5.2身份認證
本服務端采用類Basic認證方案后专,在HTTPS協(xié)議頭加入屬性Authorization划鸽,其值由認證方案和base64編碼后的用戶名和APP ID組成。(除登錄以外每次請求必須在協(xié)議頭添加身份認證)
1)認證方式(暫定)
參數介紹:
userid = ghml//用戶名
appid = TaxiManager01//分配給的APPID
編碼規(guī)則:
a)用:號連接用戶名和APPID
gmhl:TaxiManager01
b)對a)得到的字符串進行base64編碼
Z21obDpUYXhpTWFuYWdlcjAx
c)認證方案和b)編碼后字符串進行連接
Basic Z21obDpUYXhpTWFuYWdlcjAx(注意Basic和base64字符串之間有1個空格)
d)加入請求的協(xié)議頭(Java ok http示例)
Request request = new Request.Builder()
.url("https://localhost:8088/api/v1/account/login")
.get()
.addHeader("authorization", "Basic Z21obDpUYXhpTWFuYWdlcjAx")
.build()
注意事項:帳號登陸以后有效時間為2個小時戚哎,每次請求都會刷新有效時間裸诽,超過2個小時沒任何操作,需要重新登陸型凳。
應用場景2
調整圖片大小
//調整圖片大小
+ (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
UIGraphicsBeginImageContext(size);
[img drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
//判斷圖片是否達到一定尺寸,達到則做處理(主要用于發(fā)送圖片到服務器時使用, 如店鋪編輯, 上傳圖片)
+ (NSData *) handleImageBySize:(UIImage *) image
{
NSData * imageData = UIImageJPEGRepresentation(image,1);
NSInteger imageSize = [imageData length] / 1024 + 30; //KB
if(imageSize < 200)
return imageData;
CGFloat imageW = 800;
CGFloat imageH = 800;
UIImage *handImage = image;
if(image.size.width > imageW || image.size.height > imageH)
{
CGFloat scale = image.size.width / image.size.height; //比例
if(image.size.width > image.size.height)
{
//橫向圖片
imageH = imageW / scale;
handImage = [self scaleToSize:image size:CGSizeMake(imageW, imageH)];
}
else
{
imageW = imageH * scale;
handImage = [self scaleToSize:image size:CGSizeMake(imageW, imageH)];
}
}
return UIImageJPEGRepresentation(handImage, 0.3);
}
//帶圖片的提交模式
- (void) submitImageDataSoapCallWithMethodName:(NSString *)methodName params:(NSDictionary *)paramsDictionary{
NSString *requestFile = [self getRequestFile];
methodName = [NSString stringWithFormat:@"%@?memberId=%@", methodName, appDelegate.appInteraction.memberId];
NSString *soapURLString = [NSString stringWithFormat:@"%@/%@/%@",defaultWebServiceUrl,requestFile,methodName];
NSString *utf8ParamValue = [soapURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"URL = %@", soapURLString);
NSURL *url = [[NSURL alloc] initWithString:utf8ParamValue];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval:120];
//分界線的標識符
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
//分界線 --AaB03x
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//結束符 AaB03x--
NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
//http body的字符串
NSMutableString *body=[[NSMutableString alloc]init];
NSMutableData *postData = [NSMutableData data];
for (NSString *param in [paramsDictionary keyEnumerator]) {
if ([[paramsDictionary objectForKey:param] isKindOfClass:[UIImage class]]) {
NSData *imageData = [Common handleImageBySize:[paramsDictionary objectForKey:param]];
if (imageData) {
NSMutableString *imgbody = [[NSMutableString alloc] init];
////添加分界線崭捍,換行
[imgbody appendFormat:@"%@\r\n",MPboundary];
[imgbody appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@.png\"\r\n", param, param];
//聲明上傳文件的格式
[imgbody appendFormat:@"Content-Type: application/octet-stream; charset=utf-8\r\n\r\n"];
//
//[imgbody appendString:@"Content-Type:image/png\r\n"];
//將body字符串轉化為UTF8格式的二進制
//[myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:[imgbody dataUsingEncoding:NSUTF8StringEncoding]];
//將image的data加入
[postData appendData:imageData];
[postData appendData:[ @"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
}
else
{
//添加分界線,換行
[body appendFormat:@"%@\r\n",MPboundary];
//添加字段名稱啰脚,換2行
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",param];
//[body appendString:@"Content-Transfer-Encoding: 8bit"];
//添加字段的值
[body appendFormat:@"%@\r\n",[paramsDictionary objectForKey:param]];
}
}
//將body字符串轉化為UTF8格式的二進制
[postData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
//聲明結束符:--AaB03x--
NSString *end=[[NSString alloc]initWithFormat:@"%@\r\n",endMPboundary];
//加入結束符--AaB03x--
[postData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
//設置HTTPHeader中Content-Type的值
NSString *content=[[NSString alloc] initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
//設置HTTPHeader
[request setValue:content forHTTPHeaderField:@"Content-Type"];
//[request setValue:@"keep-alive" forHTTPHeaderField:@"connection"];
//[request setValue:@"UTF-8" forHTTPHeaderField:@"Charsert"];
//設置Content-Length
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[postData length]] forHTTPHeaderField:@"Content-Length"];
//設置http body
[request setHTTPBody:postData];
//http method
[request setHTTPMethod:@"POST"];
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
isTimeout = NO;
if( connectionError)
{
[self interfaceError:connectionError];
}
else
{
if(data)
{
NSError *error;
NSString *AXMLString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"AXMLString=%@", AXMLString);
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
if(error != nil)
{
//NSLog(@"error = %@", error);//有誤
[self interfaceError:error];
}
else
{
if(! isCancel)
[self.delegate requestFinishedMessage:dic];
}
}
}
}];
}