HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的协议。它是一种无状态的、应用层的协议,用于在计算机之间传输超文本文档,通常在 Web 浏览器和 Web 服务器之间进行数据通信。HTTP 是由互联网工程任务组(IETF)定义的,它是基于客户端-服务器模型的协议,其中客户端向服务器发送请求,服务器以相应的数据作为响应。HTTP 协议是建立在 TCP/IP 协议之上的,通常使用默认的端口号80。
以下是 HTTP 的一些关键特点:
- 文本协议: HTTP 是一种文本协议,通过纯文本的方式传输数据。这使得它易于阅读和调试,但也带来了一些安全性方面的问题,因此在需要更安全的通信时,通常会使用 HTTPS(HTTP Secure)来加密通信内容。
- 无状态协议: HTTP 是一种无状态协议,意味着每个请求和响应之间都是相互独立的,服务器不会保存关于客户端的任何状态信息。这导致了一些问题,例如在进行用户身份验证时,需要额外的机制来保持状态。
- 请求方法: HTTP 定义了一组请求方法,其中最常见的包括 GET(获取资源)、POST(提交数据)、PUT(更新资源)、DELETE(删除资源)等。这些方法指示了客户端对服务器执行的操作。
- 状态码: 服务器在响应中返回一个状态码,用于表示请求的处理结果。常见的状态码包括200(OK,请求成功)、404(Not Found,未找到请求的资源)、500(Internal Server Error,服务器内部错误)等。
- URL(Uniform Resource Locator): HTTP 使用 URL 来标识和定位网络上的资源。URL 包括协议部分(如 "http://")、主机名(如 "www.example.com")、路径部分(如(-lm3g6611ahhripqxl6lpyi/) "/path/to/resource")等。
- Header(报头): HTTP 的请求和响应中都包含头部信息,用于传递关于消息的附加信息。头部可以包含各种信息,如身份验证信息、内容类型、缓存控制等。
HTTP 是万维网上数据通信的基础,它定义了客户端和服务器之间的通信规范。它支持超文本(Hypertext),使得用户能够通过点击链接访问和浏览相关的文档和资源,是构建 Web 应用程序的重要基础之一。
Web路径分割
如下提供的代码片段包含了两个用于分割URL的函数:HttpUrlSplitA
和HttpUrlSplitB
。这些函数的目的是从给定的URL中提取主机名和路径。下面是对两个函数的概述:
HttpUrlSplitA
函数:- 使用Windows API的
InternetCrackUrl
函数,该函数专门用于解析URL。 - 通过
URL_COMPONENTS
结构体来传递和接收URL的不同部分,包括主机名和路径。 - 适用于对URL进行标准化处理的情境,直接调用系统提供的功能。
- 使用Windows API的
HttpUrlSplitB
函数:- 手动实现对URL的解析,通过检查URL的开头,然后手动提取主机名和路径。
- 对URL进行了一些基本的检查,如是否以 "http://" 或 "https://" 开头。
- 提供了一种更灵活的方式,但需要开发者自己处理解析逻辑。
总体而言,这两个函数都属于URL处理的一部分,但选择使用哪个函数可能取决于具体的项目需求和开发者的偏好。HttpUrlSplitA
直接利用Windows API提供的功能,更为直观。而HttpUrlSplitB
则通过手动解析,提供了更多的控制权。在实际项目中,选择取决于开发者对项目的要求和对代码控制的需求。
InternetCrackUrl
用于解析 URL。它将 URL 拆分为各个组成部分,例如协议、主机名、端口、路径等。这个函数的目的是方便开发者处理 URL,以便更容易地获取和使用其中的信息。
以下是关于 InternetCrackUrl
函数的一些关键信息:
BOOL InternetCrackUrl(
_In_ PCTSTR lpszUrl,
_In_ DWORD dwUrlLength,
_In_ DWORD dwFlags,
_Out_ LPURL_COMPONENTS lpUrlComponents
);
lpszUrl
: 指向包含 URL 字符串的空终止字符串的指针。dwUrlLength
: URL 字符串的长度,如果是 NULL 终止字符串,可以设置为DWORD(-1)
。dwFlags
: 一组标志,用于指定解析行为。lpUrlComponents
: 指向一个URL_COMPONENTS
结构体的指针,该结构体用于接收 URL 的各个组成部分。
URL_COMPONENTS
结构体包括以下字段:
typedef struct _URL_COMPONENTS {
DWORD dwStructSize;
LPTSTR lpszScheme;
DWORD dwSchemeLength;
INTERNET_SCHEME nScheme;
LPTSTR lpszHostName;
DWORD dwHostNameLength;
INTERNET_PORT nPort;
LPTSTR lpszUserName;
DWORD dwUserNameLength;
LPTSTR lpszPassword;
DWORD dwPasswordLength;
LPTSTR lpszUrlPath;
DWORD dwUrlPathLength;
LPTSTR lpszExtraInfo;
DWORD dwExtraInfoLength;
} URL_COMPONENTS, *LPURL_COMPONENTS;
dwStructSize
: 结构体大小。lpszScheme
: 指向字符串的指针,该字符串包含 URL 的方案部分(如 "http")。nScheme
: 表示 URL 方案的整数值。lpszHostName
: 指向字符串的指针,包含主机名部分。nPort
: 表示端口号。lpszUserName
和lpszPassword
: 分别是用户名和密码的部分。lpszUrlPath
: URL 路径部分。lpszExtraInfo
: 额外信息。
InternetCrackUrl
的返回值为 BOOL
类型,如果函数成功,返回非零值,否则返回零。函数成功后,lpUrlComponents
结构体中的字段将被填充。
这个函数通常用于在网络编程中处理 URL,例如在创建网络请求时提取主机名、端口和路径。
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include <WinInet.h>
#pragma comment(lib, "WinInet.lib")
#pragma comment(lib,"ws2_32")
using namespace std;
// 通过InternetCrackUrl函数实现切割
BOOL HttpUrlSplitA(const char* URL, LPSTR pszHostName, LPSTR pszUrlPath)
{
BOOL bRet = FALSE;
URL_COMPONENTS url_info = { 0 };
RtlZeroMemory(&url_info, sizeof(url_info));
url_info.dwStructSize = sizeof(url_info);
url_info.dwHostNameLength = MAX_PATH - 1;
url_info.lpszHostName = pszHostName;
url_info.dwUrlPathLength = MAX_PATH - 1;
url_info.lpszUrlPath = pszUrlPath;
bRet = InternetCrackUrl(URL, 0, 0, &url_info);
if (FALSE == bRet)
{
return FALSE;
}
return TRUE;
}
int main(int argc, char* argv[])
{
char szHostName[1024] = { 0 };
char szUrlPath[1024] = { 0 };
BOOL flag = HttpUrlSplitA("http://www.xxx.com/index.html", szHostName, szUrlPath);
if (flag == TRUE)
{
printf("输出主路径:%s n", szHostName);
printf("输出子路径:%s n", szUrlPath);
}
system("pause");
return 0;
}
运行后则会对http://www.xxx.com/index.html
字符串进行路径切割,并输出主目录与子路径,如下图所示;
相对于使用原生API切割,自己实现也并不难,如下所示,通过_strnicmp
判断字符串长度并切割特定的位置,实现对字符串的切割;
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include <WinInet.h>
#pragma comment(lib, "WinInet.lib")
#pragma comment(lib,"ws2_32")
using namespace std;
// 自己实现对URL路径的拆分
bool HttpUrlSplitB(const char* pszUrl)
{
char szHost[256] = { 0 };
char* ptr = (char*)pszUrl;
// 判断开头是否为http:// 或者 https:// 如果不是则返回-1
if (_strnicmp(ptr, "http://", 7) == 0)
{
ptr = ptr 7;
}
else if (_strnicmp(ptr, "https://", 8) == 0)
{
ptr = ptr 8;
}
else
{
return false;
}
int index = 0;
while (index < 255 && *ptr && *ptr != '/')
{
szHost[index ] = *ptr ;
}
szHost[index] = '