WEB通用网关接口:CGI简单教程
?
CGI 全稱為Common Gateway Interface (通用網關接口),目的是能夠讓服務器能夠方便的調用外部程序。
CGI本身是一套協議和規范,原則上只要是擁有讀寫文件功能的編程語言都可以用來編寫CGI程序,例如C,C++,Perl,Visual Basic,Shell等等,歷史上用來編寫CGI程序使用最廣泛的是Perl語言,連PHP一開始也是用Perl編寫的,估計也受這個傳統的影響。服務器在認為這是一個CGI請求時,會調用相關CGI程序,并通過環境變量和標準輸出將數據傳送給CGI程序,CGI程序處理完數據,生成html,然后再通過標準輸出將內容返回給服務器,服務器再將內容交給用戶,CGI進程退出,在這個過程中,服務器的標準輸出對應了CGI程序的標準輸入,CGI程序的標準輸出對應著服務器的標準輸入,相當于利用兩條管道建立了進程間的通信。
CGI程序可能會調用其它應用或API來完成用戶提交的請求。
?
現在CGI一般不再用于直接返回html頁面,同時將復雜的計算、IO任務下沉到后端。使CGI作為前后端之間的中間層。彼時CGI的職能是完成基本的數據交換:解析前端數據請求,再轉發給對應后端;然后從后端取回數據,給前端返回XML或JSON。
?
參考:
-
https://blog.csdn.net/zhang197093/article/details/73555895
-
https://www.jdon.com/idea/cgi.htm
?
?
?
測試環境:Ubuntu?gnome(16.04)版 +?win10? (win10上運行Ubuntu虛擬機)
?
1.?安裝thttpd
參考:https://blog.csdn.net/u012247418/article/details/90137417
?
?
2.?編寫index.html
<h1>A Simple CGI Test</h1> <form action="/cgi-bin/test-cgi.cgi" method="get"> <table> <tr> <td>User Name: </td> <td><input name="username"/></td> </tr> <tr> <td>Password: </td> <td><input name="password"/></td> </tr> <tr> <td><input type="submit" value="OK"/></td> </tr> </table> </form>利用GET向服務器發送請求,并將用戶數據(Name&Password)作為URL的一部分發送到服務器。
?
?
3.?編寫CGI程序
CGI程序可以用多種語言來編寫,當然也包括C/C++。
1) test-cgi.c
#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc, char *argv[]) {char *query_string = "FAILD";char *request_mthod = getenv("REQUEST_METHOD");if((request_mthod != NULL) && (strncmp(request_mthod, "GET", 3) == 0)){query_string = getenv("QUERY_STRING");}printf("Content-type:text/html\n\n");printf("<html>\n");printf("<head><title>An html page from a cgi</title></head>\n");printf("<body>\n");printf("<h1>query string: %s</h1>\n", query_string);printf("</body>\n");printf("</html>\n");fflush(stdout);return 0; }先判斷客戶端請求是否為“GET”,如果是則獲取請求參數,最后將請求參數再原封不動的返回至客戶端。
?
2) 編譯:gcc?test-cgi.c -o?test-cgi.cgi
?
?
4.?修改配置
4.1?創建目錄
baoli@ubuntu:~/tools/thttpd/html1$ tree
.
├── cgi-bin
│???└── test-cgi.cgi
└── index.html
?
1 directory, 2 files
?
4.2?修改thttpd.conf
# This section overrides defaults dir=/home/baoli/tools/thttpd/html1 # chroot user=baoli# default = nobody logfile=/var/log/thttpd.log pidfile=/var/run/thttpd.pid # This section _documents_ defaults in effect # port=80 # nosymlink# default = !chroot # novhost cgipat=/cgi-bin/* # nothrottles # host=0.0.0.0 # charset=iso-8859-1?
說明:
1)cgipat=/cgi-bin/*
聲明CGI程序的目錄,這里的'/'根目錄并非Ubuntu系統的根目錄,而是以dir=/home/baoli/tools/thttpd/html1?作為根目錄。
2)屏蔽chroot是為了運行動態編譯的CGI程序
?
?
5.?測試
在windows?瀏覽器輸入:http://192.168.0.104
?
?
?
6.?CGI環境變量
| 環境變量 | 意義 |
| SERVER_NAME | CGI腳本運行時的主機名和IP地址. |
| SERVER_SOFTWARE | 你的服務器的類型如: CERN/3.0 或 NCSA/1.3. |
| GATEWAY_INTERFACE | 運行的CGI版本. 對于UNIX服務器, 這是CGI/1.1. |
| SERVER_PROTOCOL | 服務器運行的HTTP協議. 這里當是HTTP/1.0. |
| SERVER_PORT | 服務器運行的TCP口,通常Web服務器是80. |
| REQUEST_METHOD | POST 或 GET, 取決于你的表單是怎樣遞交的. |
| HTTP_ACCEPT? | 瀏覽器能直接接收的Content-types, 可以有HTTP Accept header定義. |
| HTTP_USER_AGENT | 遞交表單的瀏覽器的名稱、版本 和其他平臺性的附加信息。 |
| HTTP_REFERER | 遞交表單的文本的 URL,不是所有的瀏覽器都發出這個信息,不要依賴它 |
| PATH_INFO | 附加的路徑信息, 由瀏覽器通過GET方法發出. |
| PATH_TRANSLATED | 在PATH_INFO中系統規定的路徑信息. |
| SCRIPT_NAME | 指向這個CGI腳本的路徑, 是在URL中顯示的(如, /cgi-bin/thescript). |
| QUERY_STRING | 腳本參數或者表單輸入項(如果是用GET遞交). QUERY_STRING 包含URL中問號后面的參數. |
| REMOTE_HOST | 遞交腳本的主機名,這個值不能被設置. |
| REMOTE_ADDR | 遞交腳本的主機IP地址. |
| REMOTE_USER | 遞交腳本的用戶名. 如果服務器的authentication被激活,這個值可以設置。 |
| REMOTE_IDENT | 如果Web服務器是在ident (一種確認用戶連接你的協議)運行, 遞交表單的系統也在運行ident, 這個變量就含有ident返回值. |
| CONTENT_TYPE | 如果表單是用POST遞交, 這個值將是 application/x-www-form-urlencoded. 在上載文件的表單中, content-type 是個 multipart/form-data. |
| CONTENT_LENGTH | 對于用POST遞交的表單, 標準輸入口的字節數. |
?
關于GET和POST
表單從瀏覽器發給服務器有兩種方法.? GET 和 POST.
我們上面談論的方法,實際是GET,它將數據打包放置在環境變量QUERY_STRING中作為URL整體的一部分傳遞給服務器。
POST做很多類似GET同樣的事情, 不同的地方就是它是分離地傳遞數據給腳本. 你的腳本通過標準輸入獲取這些數據. (有些Web服務器是存儲在臨時文件中.) 這個QUERY_STRING環境變量將不再設置.
那你用那個方法呢? POST是個安全的方法, 尤其如果你的表單中有很多數據的話. 當你用GET, 這個服務器就分配變量QUERY_STRING給所有的表單數據, 但是這個變量可存儲量是有限的. 換句話說,如果你有很多數據但是你又用GET,你會丟失很多數據.
?
?
總結
以上是生活随笔為你收集整理的WEB通用网关接口:CGI简单教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 代码单元测试工具:gmock
- 下一篇: 什么什么大冒险手游特点