什么是HTTP
超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信。
HTTP 的工作方式是客户端与服务器之间的请求-应答协议。
web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端。
举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。
- GET:从指定的资源请求数据。
- POST:向指定的资源提交要被处理的数据。
关于GET和POST的一些区别
GET | POST |
---|
Get 是用来从服务器上获得数据 | Post 是用来向服务器上传递数据 | Get 将表单中数据的按照 variable=value 的形式,添加到 action 所指向的 URL 后面,并且两者使用“?”连接,而各个变量之间使用“&”连接 | Post 是将表单中的数据放在 form 的数据体中,按照变量和值相对应的方式,传递到 action 所指向 URL。 | Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中,而如今现有的很多服务器、代理服务器或者用户代理都会将请求URL记录到日志文件中,然后放在某个地方,这样就可能会有一些隐私的信息被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前 | Post 的所有操作对用户来说都是不可见的 | Get 传输的数据量小,这主要是因为受 URL 长度限制 | Post 可以传输大量的数据,所以在上传文件只能使用 Post | Get 限制 Form 表单的数据集的值必须为 ASCII 字符 | Post 支持整个 ISO10646 字符集。 | Get 是 Form 的默认方法 | |
使用 Post 传输的数据,可以通过设置编码的方式正确转化中文;而 Get 传输的数据却没有变化。在以后的程序中,我们一定要注意这一点。
其他 HTTP 请求方法
方法 | 描述 |
---|
HEAD | 与 GET 相同,但只返回 HTTP 报头,不返回文档主体 | PUT | 上传指定的 URI 表示 | DELETE | 删除指定资源 | OPTIONS | 返回服务器支持的 HTTP 方法 | CONNECT | 把请求连接转换到透明的 TCP/IP 通道 |
如果想尝试在线使用这些HTTP方法,可以使用这个网站进行验证:http://www.ouapi.com/ 最后,仿照这个网站,做出了一个界面。
POST方法
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的,是向服务器来传递数据。
POST /test/demo_form.php HTTP/1.1
Host: runoob.com
name1=value1&name2=value2
有关 POST 请求的其他一些注释:
- POST 请求不会被缓存
- POST 请求不会保留在浏览器历史记录中
- POST 不能被收藏为书签
- POST 请求对数据长度没有要求
using System.Net.Http;
using System.Net;
Encoding myEncoding = Encoding.GetEncoding("gb2312");
string data = "sn=" + _uScanCode + "&lanMac=" + _sRecieveLanMac + "&wifiMac=" + _sRecieveWifi2Mac + "&testUserName=" + sTestUser + "&testDateTime=" + sTimeStr;
byte[] bytesToPost = System.Text.Encoding.Default.GetBytes(data);
string responseResult = String.Empty;
HttpWebRequest req = (HttpWebRequest)
HttpWebRequest.Create("http://192.168.60.59:81/rpc/snBurn/insertBySN");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
req.ContentLength = bytesToPost.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bytesToPost, 0, bytesToPost.Length);
}
HttpWebResponse cnblogsRespone = (HttpWebResponse)req.GetResponse();
if (cnblogsRespone != null && cnblogsRespone.StatusCode == HttpStatusCode.OK)
{
StreamReader sr;
using (sr = new StreamReader(cnblogsRespone.GetResponseStream()))
{
responseResult = sr.ReadToEnd();
}
sr.Close();
}
cnblogsRespone.Close();
GET方法
请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的,是从服务器上来获取数据。
/test/demo_form.php?name1=value1&name2=value2
有关 GET 请求的其他一些注释:
- GET 请求可被缓存
- GET 请求保留在浏览器历史记录中
- GET 请求可被收藏为书签
- GET 请求不应在处理敏感数据时使用
- GET 请求有长度限制
- GET 请求只应当用于取回数据
简单发送GET请求,不带参数
public static string Get(string url)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
try
{
using (StreamReader reader = new StreamReader(stream))
{
result = reader.ReadToEnd();
}
}
finally
{
stream.Close();
}
return result;
}
带参数请求的GET方法
public static string Get(string url, Dictionary<string, string> dic)
{
string result = "";
StringBuilder builder = new StringBuilder();
builder.Append(url);
if (dic.Count > 0)
{
builder.Append("?");
int i = 0;
foreach (var item in dic)
{
if (i > 0)
builder.Append("&");
builder.AppendFormat("{0}={1}", item.Key, item.Value);
i++;
}
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(builder.ToString());
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
try
{
using (StreamReader reader = new StreamReader(stream))
{
result = reader.ReadToEnd();
}
}
finally
{
stream.Close();
}
return result;
}
自定义指定Http请求头,自定义指定编码解析返回结果
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "GET";
req.Headers["Accept-Language"] = "zh-CN,zh;q=0.8";
req.Referer = "https://www.baidu.com/";
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
string result = "";
using (StreamReader reader = new StreamReader(stream, Encoding.GetEncoding("gb2312")))
{
result = reader.ReadToEnd();
}
PUT方法
PUT 用于将数据发送到服务器来创建/更新资源。
POST 和 PUT之间的区别在于 PUT 请求是幂等的(idempotent)。也就是说,多次调用相同的 PUT 请求将始终产生相同的结果。相反,重复调用POST请求具有多次创建相同资源的副作用。
public static string HttpRequest(string url, string data, string method = "PUT", string contentType = "application/json", Encoding encoding = null)
{
byte[] datas = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
if (encoding == null)
encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = method;
request.Timeout = 150000;
request.AllowAutoRedirect = false;
if (!string.IsNullOrEmpty(contentType))
{
request.ContentType = contentType;
}
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
}
Stream requestStream = null;
string responseStr = null;
try
{
if (datas != null)
{
request.ContentLength = datas.Length;
requestStream = request.GetRequestStream();
requestStream.Write(datas, 0, datas.Length);
requestStream.Close();
}
else
{
request.ContentLength = 0;
}
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
{
Stream getStream = webResponse.GetResponseStream();
byte[] outBytes = ReadFully(getStream);
getStream.Close();
responseStr = Encoding.UTF8.GetString(outBytes);
}
}
catch (Exception)
{
throw;
}
finally
{
request = null;
requestStream = null;
}
return responseStr;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
public static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[512];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
HEAD方法
HEAD 与 GET 几乎相同,但没有响应主体。
换句话说,如果 GET /users 返回用户列表,那么 HEAD /users 将发出相同的请求,但不会返回用户列表。
HEAD 请求对于在实际发出 GET 请求之前(例如在下载大文件或响应正文之前)检查 GET 请求将返回的内容很有用。
static async void HttpClientSendAsync()
{
var client = new HttpClient(new HttpClientHandler { UseProxy = false });
var request = new HttpRequestMessage(HttpMethod.Post, "http://www.albahari.com/EchoPost.aspx");
request.Content = new StringContent("This is a test!");
HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
DELETE 方法
DELETE 方法删除指定的资源
OPTIONS 方法
OPTIONS 方法描述目标资源的通信选项
格式化JSON数据
using Newtonsoft.Json;
static public string ConvertJsonString(string json)
{
JsonSerializer serializer = new JsonSerializer();
TextReader tr = new StringReader(json);
JsonTextReader jtr = new JsonTextReader(tr);
object obj = serializer.Deserialize(jtr);
if (obj != null)
{
StringWriter textWriter = new StringWriter();
JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
{
Formatting = Formatting.Indented,
Indentation = 4,
IndentChar = ' '
};
serializer.Serialize(jsonWriter, obj);
return textWriter.ToString();
}
else
{
return json;
}
}
参考文献
|