对于任何一个程序员来说HTTP协议都是大家肯定会用到协议,不管是你是哪种语言的开发者,详细你不会陌生,HTTP是基于TCP/IP之上的,Http协议目前常用的是1.1版本所以,我也是吸取众家之所长做一个笔记,留给自己和初学者,并不长篇大论,只挑最常用的说
请求Method:有GET和POST最为常用,其中GET只通过URL传递参数,而POST功能强大用来传输表单数据,以及上传文件
请求Head:
Host | 客户机向服务器发送请求的主机名 ,例子:192.168.1.101/index.html |
Accept | 客户机支持的数据类型,例子:text/html |
Accept-Language | 客户机支持的语言,例子:zh_CN |
Accept-Charset | 客户机支持的编码,例子:utf-8 |
Accept-Encoding | 客户机的压缩格式,例子:gzip |
Referer | 客户机访问此资源的来源;比如从1.html中的超链接请求2.html,则请求2.html时会发送Referer: 1.html 用途:防盗链避免从未知网站链接此网站,盗用资源 |
User-Agent | 客户机的软件环境,这个东西常用来判断浏览器类型: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 |
Connection | 客户机发送此连接后的连接状态时继续连接还是断开,列子:keep-alive |
Date | 客户机发送的时间 |
请求Body:请求Body也是不得不重点说的一个东西,因为很多语言的API虽然Head有设置的函数,但是Body在一些特殊情况下需要我们自己拼装如multipart/form-data情况
例子:
POST localhost HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.1.101
Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36
Content-Length: 3693
Connection: Keep-Alive
-------------------------------7db372eb000e2
Content-Disposition: form-data; name="mykey"
789
-------------------------------7db372eb000e2
Content-Disposition: form-data; name="file"; filename="mm.jpg"
Content-Type: image/jpeg
(此处省略jpeg文件二进制数据...)
-------------------------------7db372eb000e2--
其中蓝色的部分就是Body,而7db372eb000e2是BOUNDARY(俗称边界线,一般是随意取个随机数就行,如果数据结束最后加--\r\n),这个边界线隔开每一个form-data,
所以我们拼装数据时候就可以吧Body按蓝色字的数据流写入,这样就完成一次Http multipart/form-data 的POST请求了
响应代码号:实际上一般记住几个就OK了,200代表正确返回,500是服务器内部错误,414 请求URL过长,400:Bad Request 请求错误
响应码分五种类型,由它们的第一位数字表示:
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求
光说不练假把式,来一段Java的代码吧,诠释一下multipart/form-data,实测有效,可以参照着改成自己本地环境试一试获取响应的代码,和实际返回的数据就够了。
String UploadURL = self.getResources().getString(R.string.TestAshx);
String BOUNDARY = UUID.randomUUID().toString();
String CONTENT_TYPE = "multipart/form-data"; //内容类型
String PREFIX = "--", LINE_END = "\r\n";
String __BOUNDARY = "--" + BOUNDARY + "\r\n"; //数据分隔线
String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志
String CHARSET = "utf-8";
try {
URL url2 = new URL(UploadURL);
HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
conn.setReadTimeout(10 * 10000000);
conn.setConnectTimeout(10 * 10000000);
conn.setDoInput(true);//允许输入流
conn.setDoOutput(true);//允许输出流
conn.setUseCaches(false);//不允许使用缓存
conn.setRequestMethod("POST");//请求方式
conn.setRequestProperty("Charset", CHARSET);//设置编码
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
conn.setRequestProperty("Cookie", "now=" + UtilsJodaTime.Format(new Date(), "yyyyMMddHHmmss") + ";");
OutputStream outputSteam = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(outputSteam);
{
StringBuffer sb = new StringBuffer();
//键值对一
sb.append(__BOUNDARY);
sb.append("Content-Disposition: form-data;name=\"abc\"\r\n\r\n789" + LINE_END);
//键值对二
sb.append(__BOUNDARY);
sb.append("Content-Disposition: form-data;name=\"qqq\"\r\n\r\n你好" + LINE_END);
dos.write(sb.toString().getBytes());
}
{
//文件一
StringBuffer sb = new StringBuffer();
sb.append(__BOUNDARY);
sb.append("Content-Disposition: form-data; name=\"myfile1\"; filename=\"123.jpg\"" + LINE_END);
sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
InputStream is = self.getResources().getAssets().open("test.jpg");
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
dos.write(LINE_END.getBytes());
}
{
//文件二
StringBuffer sb = new StringBuffer();
sb.append(__BOUNDARY);
sb.append("Content-Disposition: form-data; name=\"myfile2\"; filename=\"" + "456.jpg" + "\""
+ LINE_END);
sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());
InputStream is = self.getResources().getAssets().open("test.jpg");
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
dos.write(LINE_END.getBytes());
}
dos.write(endline.getBytes());
dos.flush();
String msg = conn.getResponseMessage();
int res = conn.getResponseCode();
if (res == HttpURLConnection.HTTP_OK) {
InputStream isresponse = conn.getInputStream();
String responseText = UtilsStream.InputStreamToString(isresponse, Charset.forName(CHARSET));
consoleView.clear();
consoleView.println(responseText, Color.BLUE);
String responseCookie = conn.getHeaderField("Set-Cookie");
consoleView.println("Set-Cookie:" + responseCookie, Color.BLUE);
}
toast("response code:" + res);
} catch (Exception e) {
// TODO: handle exception
toast(e.toString());
}
但是不得不说还有一个Cookie,关于Cookie的格式也可以长篇大论一番了,不过上面的代码也实现了Cookie,有空再贴出C#版本的。