目录
一.HTTP 简介
超文本传输协议(HTTP - Hypertext Transfer Protocol)是用于在万维网(WWW - World Wide Web)上传输信息的应用层协议。它定义了客户端(通常是 Web 浏览器)和服务器之间交换数据的格式和规则。HTTP 是互联网上使用最广泛的协议之一,是万维网的基础。
HTTP 工作原理
HTTP 使用请求-响应模式进行通信。客户端向服务器发送请求,服务器接收请求并发送响应。请求和响应都由消息组成,消息包含用于描述请求或响应的信息的头和数据主体。
HTTP 请求
HTTP 请求包含以下信息:
- 请求方法: 指定客户端希望对资源执行的操作,例如 GET、POST、PUT、DELETE 等。
- URL: 指定要请求的资源的地址。
- 请求头: 提供有关客户端和请求的其他信息,例如 User-Agent、Accept、Content-Type 等。
- 请求主体: 可选,包含客户端要发送给服务器的数据。
HTTP 响应
HTTP 响应包含以下信息:
- 状态码: 指示请求是否成功,例如 200 OK、404 Not Found、500 Internal Server Error 等。
- 响应头: 提供有关服务器和响应的其他信息,例如 Content-Type、Content-Length、Date 等。
- 响应主体: 可选,包含服务器要发送给客户端的数据。
HTTP 的常见应用
HTTP 用于各种网络应用,包括:
- 浏览网页: 当您在 Web 浏览器中输入 URL 时,浏览器会向相应的服务器发送 HTTP 请求以获取网页。服务器会发送 HTTP 响应,其中包含网页的 HTML 代码。
- 发送和接收文件: HTTP 可用于在客户端和服务器之间发送和接收文件。例如,当您从网站下载文件时,浏览器会向服务器发送 HTTP 请求以获取文件。服务器会发送 HTTP 响应,其中包含文件数据。
- API 调用: 许多应用程序使用 HTTP 进行 API 调用。例如,当您使用移动应用程序时,该应用程序可能会向服务器发送 HTTP 请求以获取数据或执行操作。
HTTP 的优点
HTTP 具有以下优点:
- 简单易用: HTTP 的协议规范相对简单易懂,易于实现和使用。
- 通用性强: HTTP 可用于传输各种类型的资源,包括文本、图像、视频、音频等。
- 可扩展性强: HTTP 可以通过添加新的请求方法、响应头和消息格式来扩展,以满足新的应用需求。
- 无状态: HTTP 是一种无状态协议,这意味着每次请求之间客户端和服务器之间都不保持任何状态信息。这使得 HTTP 协议非常高效且易于扩展。
HTTP 的缺点
HTTP 也有以下缺点:
- 不安全: HTTP 是明文协议,这意味着请求和响应中的数据没有加密,可能会被窃听或篡改。
- 效率不高: HTTP 使用请求-响应模式,这可能会导致大量往返通信,尤其是在传输大型资源时。
- 不支持长连接: HTTP 默认使用短连接,这意味着每次请求都需要建立新的连接,这可能会降低性能。
二.使用 CHtmlView 类创建 Web 视图
CHtmlView 类是 MFC 框架中用于显示 HTML 内容的控件。它可以用来创建 Web 浏览器、电子邮件阅读器等应用程序。
创建 CHtmlView 控件
要创建 CHtmlView 控件,请执行以下步骤:
- 在对话框或其他窗口的资源编辑器中,将 CHtmlView 控件添加到对话框或窗口的布局中。
- 在对话框或窗口的代码中,创建 CHtmlView 控件的对象。
- 调用 CHtmlView 对象的 Navigate2 方法来加载 HTML 文档。
以下是一个创建 CHtmlView 控件并加载 HTML 文档的示例代码:
CHtmlView m_htmlView;
BOOL CWnd::OnInitDialog()
{
BOOL bSuccess = CWnd::OnInitDialog();
if (bSuccess)
{
// 创建 CHtmlView 控件
CRect rect(10, 10, 300, 200);
m_htmlView.Create(WS_VISIBLE | WS_CHILD, rect, this, IDC_HTMLVIEW);
// 加载 HTML 文档
m_htmlView.Navigate2(_T("https://www.example.com"));
}
return bSuccess;
}
CHtmlView 类成员函数
CHtmlView 类提供了许多成员函数来控制 Web 视图的行为。以下是一些常用的成员函数:
- Navigate2: 加载 HTML 文档。
- GoBack: 返回到上一页。
- GoForward: 进入下一页。
- Refresh: 刷新当前页面。
- Stop: 停止加载当前页面。
- GetDocument: 获取当前加载的 HTML 文档。
CHtmlView 类事件
CHtmlView 类提供了许多事件来通知应用程序有关 Web 视图的状态变化。以下是一些常用的事件:
- OnBeforeNavigate2: 在加载新页面之前触发。
- OnNavigate2: 在加载新页面之后触发。
- OnTitleChange: 在页面标题更改时触发。
- OnStatusChange: 在页面状态更改时触发。
- OnProgressChange: 在页面加载进度更改时触发。
使用 CHtmlView 类创建 Web 浏览器
可以使用 CHtmlView 类创建简单的 Web 浏览器。以下是一个示例代码:
// MyHtmlView.h
#pragma once
#include <afxhtml.h>
class CMyHtmlView : public CHtmlView
{
protected: // create from serialization only
CMyHtmlView() noexcept;
DECLARE_DYNCREATE(CMyHtmlView)
public:
virtual ~CMyHtmlView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
public:
virtual void OnInitialUpdate();
DECLARE_MESSAGE_MAP()
};
// MyHtmlView.cpp
#include "stdafx.h"
#include "MyHtmlView.h"
IMPLEMENT_DYNCREATE(CMyHtmlView, CHtmlView)
BEGIN_MESSAGE_MAP(CMyHtmlView, CHtmlView)
END_MESSAGE_MAP()
CMyHtmlView::CMyHtmlView() noexcept
{
}
CMyHtmlView::~CMyHtmlView()
{
}
#ifdef _DEBUG
void CMyHtmlView::AssertValid() const
{
CHtmlView::AssertValid();
}
void CMyHtmlView::Dump(CDumpContext& dc) const
{
CHtmlView::Dump(dc);
}
#endif //_DEBUG
void CMyHtmlView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
Navigate2(_T("https://www.example.com")); // Navigate to your desired URL
}
在主框架视图中,你需要使用类向导将该视图添加到你的应用程序中。在 CMainFrame
中的 OnCreateClient
方法中创建一个 CHtmlView
视图对象。
// MainFrm.cpp
#include "stdafx.h"
#include "MainFrm.h"
#include "MyHtmlView.h"
...
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
// 创建 HTML 视图
m_wndSplitter.CreateStatic(this, 1, 2);
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView), CSize(100, 100), pContext);
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyHtmlView), CSize(100, 100), pContext);
return TRUE;
}
三.Web 浏览器应用程序示例
完善一个简单的 Web 浏览器应用程序,除了基本的浏览功能外,还可以考虑添加一些额外的功能,比如前进、后退、刷新等。以下是一个更完整的示例:
// MyWebBrowser.h
#pragma once
#include <afxhtml.h>
class CMyWebBrowser : public CHtmlView
{
protected:
DECLARE_DYNAMIC(CMyWebBrowser)
public:
CMyWebBrowser();
virtual ~CMyWebBrowser();
void Navigate(LPCTSTR lpszURL);
void NavigateBack();
void NavigateForward();
void Refresh();
protected:
DECLARE_MESSAGE_MAP()
};
// MyWebBrowser.cpp
#include "stdafx.h"
#include "MyWebBrowser.h"
IMPLEMENT_DYNAMIC(CMyWebBrowser, CHtmlView)
BEGIN_MESSAGE_MAP(CMyWebBrowser, CHtmlView)
END_MESSAGE_MAP()
CMyWebBrowser::CMyWebBrowser()
{
}
CMyWebBrowser::~CMyWebBrowser()
{
}
void CMyWebBrowser::Navigate(LPCTSTR lpszURL)
{
Navigate2(lpszURL, NULL, NULL);
}
void CMyWebBrowser::NavigateBack()
{
GoBack();
}
void CMyWebBrowser::NavigateForward()
{
GoForward();
}
void CMyWebBrowser::Refresh()
{
Refresh2();
}
然后,在你的主框架类中,可以添加按钮或菜单项来执行这些操作:
// MainFrm.h
#pragma once
#include "MyWebBrowser.h"
class CMainFrame : public CFrameWnd
{
// ...
protected:
CMyWebBrowser m_webBrowser;
// ...
afx_msg void OnNavigateBack();
afx_msg void OnNavigateForward();
afx_msg void OnNavigateRefresh();
// ...
};
// MainFrm.cpp
#include "stdafx.h"
#include "MainFrm.h"
// ... 其他包含的头文件
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
// ...
ON_COMMAND(ID_NAVIGATE_BACK, &CMainFrame::OnNavigateBack)
ON_COMMAND(ID_NAVIGATE_FORWARD, &CMainFrame::OnNavigateForward)
ON_COMMAND(ID_NAVIGATE_REFRESH, &CMainFrame::OnNavigateRefresh)
// ...
END_MESSAGE_MAP()
CMainFrame::CMainFrame()
{
// ...
}
void CMainFrame::OnNavigateBack()
{
m_webBrowser.NavigateBack();
}
void CMainFrame::OnNavigateForward()
{
m_webBrowser.NavigateForward();
}
void CMainFrame::OnNavigateRefresh()
{
m_webBrowser.Refresh();
}
在资源文件中定义这些菜单项,并在应用程序启动时初始化浏览器:
// MainFrm.cpp 中的 CMainFrame 构造函数中
CMainFrame::CMainFrame()
{
// ...
if (!m_webBrowser.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create web browser\n");
}
else
{
m_webBrowser.Navigate(_T("https://www.example.com"));
}
}