使用C ++创建网站

这可能吗?


是的

我知道这听起来很奇怪,看起来更像是在毫无价值的练习中,但事实并非如此。
在本文中,我将告诉您如何在网站开发中使用C ++,并为此提供一些充分的理由。

这不仅会很有趣,而且会很有用而且非常实用。

代管


您可能会认为:这种异常的配置只能在专门的环境中实现。 但是,通常不是这种情况。 尽管对于许多站点(不仅仅是C ++站点)而言,常规或虚拟专用服务器都是理想的解决方案,但是在大多数情况下,您可以在共享主机服务上使用C ++。
任何支持CGI的Web托管(原则上就是所有内容)都将能够支持C ++网站。 根据提供者的不同,您可以在本地编译站点,也可以不在本地编译站点,并且您的帐户中需要包含编译器。 如果您计划直接在Web服务器上通过SSH编辑和编译,请检查一下。

简单的例子


在以上示例中,我使用了cPanel托管帐户。 它们价格适中,便宜且稳定。 但是,您可以通过一些简单的Apache配置修改轻松地将这些方法调整为虚拟或专用服务器或Amazon EC2实例。

cPanel为我们提供了cgi-bin文件夹,但我们不需要它。 在大多数情况下,具有扩展名.cgi的文件如果具有正确的权限(通常为0755),将被自动处理。 这是必要的文件(请确保在Makefile中使用TAB)

生成文件:

all: g++ -O3 -s hello.cpp -o hello.cgi clean: rm -f hello.cgi 

hello.cpp:

 #include <iostream> #include <string> #include <stdlib.h> using namespace std; void set_content_type(string content_type) { cout << "Content-type: " << content_type << "\r\n\r\n"; } void set_page_title(string title) { cout << "<title>" << title << "</title>\n"; } void h1_text(string text) { cout << text << "\n"; } int main() { set_content_type("text/html"); // Output HTML boilerplate cout << "<!doctype html>\n"; cout << "<html lang=\"en\">\n"; cout << "<head>\n"; set_page_title("Hello, World!"); cout << "</head>\n"; cout << "<body>\n"; h1_text("Hello, World!"); cout << "</body>\n"; cout << "</html>"; return 0; } 

如果您的帐户中包含编译器(可能需要向网络托管服务支持小组咨询),只需在您的帐户中使用SSH,然后将这些文件放在public_html文件夹中,然后执行以下操作:

 make 

hello.cgi文件将被执行。 例如,如果在浏览器中输入文件地址,则如下所示:

 http://your-test-site.com/hello.cgi 

然后,用您的域名或托管URL替换your-test-site.com。 屏幕上应出现“ Hello World”。

在深入研究代码本身之前,让我们看一下它在Web服务器上的工作方式。 当Apache接受请求时,它首先查看的是内部处理程序或覆盖规则,然后在磁盘上查找与请求匹配的文件。 在我们的例子中,它找到hello.cgi并检索它。 我们的程序不接受输入,而仅显示消息“ Hello world”。 然后,Apache接收此数据并将其返回给用户。

说到代码,应该提到它可能会更容易。 不必包含单独的函数set_content_type,set_page_title和h1_text。 有简单的助手可以保持主要功能的整洁。 所有这些都可以简单地带到主函数中,并且将以完全相同的方式工作。

但我希望您能看到突出这些功能的优势。 如果需要为每个HTML元素创建一个函数,则可以使用以下代码在程序中创建干净的响应:

 void p(string text) { cout << "<p>" << text << "</p>\n"; } 

然后使用类似:

 p("This would be paragraph text."); 

显示一个段落。

您甚至可以提出这个想法,以便帮助函数(如p,h1_text等)返回文本,而不是通过cout直接输出到标准输出。 同时,您可以创建模板系统或嵌套答案,以使用非常精简且高效的C ++代码创建复杂的页面。

该示例尽可能简单,仅指示要点。 您具有对每个响应头的完全访问权限,从而可以完全控制响应循环。

有关输入的更多信息


我们的示例不接受任何输入,仅返回“ Hello World”。 但是Apache通过环境变量为每个请求提供了大量信息。 您可以使用C标准库中的getenv()函数获取它们的值(不要忘了在代码开头添加#include <stdlib.h>)。例如,如果您需要找出完整的请求URI,则可以使用:

 string request_uri = getenv("REQUEST_URI"); 

获得此值。 其他有用的变量:

  • REMOTE_ADDR-获取访客的IP地址
  • REQUEST_METHOD-返回方法(即GET,POST等)
  • DOCUMENT_ROOT-站点的路由(在共享系统上通常为〜/ public_html,在虚拟/专用服务器上通常为/ var / www / html)。
  • QUERY_STRING-查询字符串以获取GET变量。

更清晰的例子


当然,可以手动解析GET变量,并且可以通过检查标准输入来完成POST变量的处理。 您甚至可以通过更改请求和响应标头来接收和设置Cookie。 但是,这两种方法都过于繁琐。

您可以编写自己的shell或使用现成的GNU cgicc库。 它包含用于修改HTML和处理表单的辅助函数。 在处理大型项目时,使用这样的库可以节省大量时间。

在Debian和Ubuntu上,可以使用以下命令安装库和头文件:

 apt install libcgicc5 libcgicc5-dev 

但是CentOS / RHEL没有自己的软件包。 要在它们上安装,请运行:

 cd /usr/local/src wget ftp://ftp.gnu.org/gnu/cgicc/cgicc-3.2.19.tar.gz tar xfz cgicc*.tar.gz cd cgicc* ./configure — prefix=/usr make make install 

注意:在撰写本文时,3.2.19是最新版本,但是您可以在ftp.gnu.org/gnu/cgicc中检查更新的副本。 我还使用/ usr作为前缀,以避免链接库出现问题。 如果有的话,请冷静地更改它们。

安装cgicc之后,您可以对其进行编译。 尝试以下示例,该示例从表单获取输入并将其显示在浏览器中:

生成文件:

 all: g++ -O3 -s hello.cpp -o hello.cgi g++ -O3 -s cgicc.cpp -o cgicc.cgi /usr/lib/libcgicc.a clean: rm -f hello.cgi cgicc.cgi 

cgicc.html:

 <!doctype html> <html lang="en"> <head> <title>cgicc Test</title> </head> <body> <form method="POST" action="cgicc.cgi"> <label for="name">Name</label> <input name="name" type="text" value=""> <input name="submit" type="submit" value="Submit"> </form> </body> </html> 

cgicc.cpp:

 #include <iostream> #include <string> #include <stdio.h> #include <stdlib.h> #include <cgicc/CgiDefs.h> #include <cgicc/Cgicc.h> #include <cgicc/HTTPHTMLHeader.h> #include <cgicc/HTMLClasses.h> using namespace std; using namespace cgicc; void set_content_type(string content_type) { cout << "Content-type: " << content_type << "\r\n\r\n"; } void set_page_title(string title) { cout << "<title>" << title << "</title>\n"; } void h1_text(string text) { cout << text << "\n"; } int main() { Cgicc cgi; string name; set_content_type("text/html"); cout << "<!doctype html>\n"; cout << "<html lang=\"en\">\n"; cout << "<head>\n"; set_page_title("cgicc Test"); cout << "</head>\n"; cout << "<body>\n"; cout << "<p>"; // Grab the "name" variable from the form name = cgi("name"); // Check to make sure it isn't empty. if (!name.empty()) { cout << "Name is " << name << "\n"; } else { cout << "Name was not provided."; } cout << "</p>\n"; cout << "</body>\n"; cout << "</html>"; return 0; } 

您可能已经注意到,我在Makefile中静态链接了cgicc库。 尽管这不是必需的(您可以用-Icgicc替换它),但我更喜欢静态链接发送到服务器的二进制代码,以便将要发送的程序所必需的所有内容都作为一个集合发送。

在此示例中,cgicc库完成了POST变量的艰苦工作,并为我们返回了“名称”。

我没有转义POST输入变量,但建议使用它,尤其是在生产场所,尤其是在与数据库交互时。

这只是cgicc可能性的一小部分。 您可以在此处阅读完整的文档。

表现/表现


C ++处理良好代码的速度非常快。 CGI接口会使事情放慢一点,但是即使这样,您也将比PHP之类的解释语言获得更好的执行。
正如他们所说,总有一些需要努力的地方。 在专业或虚拟环境中,可以使用Nginx或Apache的FastCGI支持来减少程序加载时的小延迟(如果服务器负载不大,则不明显)。 我的测试没有任何延迟,但是对于使用载流量的网站来说,研究这些解决方案以更快地执行/快速工作将非常有用。

选配


将C ++程序包装在一个薄的Docker容器中将很容易。 这将在您放置网站时为您提供极大的灵活性。 您还可以通过在程序中包含C / C ++ MySQL开发标头来访问MySQL数据库。 如果您熟悉将MySQL与PHP结合使用,您会注意到变量名非常相似。

您可以包括ImageMagick C ++标头来直接在程序中处理这些图像,而不是创建其他用于图像处理的命令行过程。

多么漫长而奇怪的旅程


用C ++创建站点是可行的,特别是在性能很重要的情况下。 我不建议在博客或个人站点上使用它-可以在WordPress上轻松完成。 但是,如果您迫切需要速度,并且希望在人迹罕至的地方写得很好,请考虑将C ++用于您在网络上的下一个细分项目。

Source: https://habr.com/ru/post/zh-CN480208/


All Articles