Python CGI programming
What is CGI
CGI currently maintained by NCSA, NCSA CGI is defined as follows:
CGI (Common Gateway Interface), Common Gateway Interface, which is a program running on the server, such as: HTTP server, the client interface providing the same HTML page.
Web browsing
To better understand how CGI works, we can click on a link on a web page or URL of the process:
- 1, use your browser to access the URL and connect to the HTTP web server.
- 2, Web server receives the request message will be parsed URL and look accessed files on the server if there is, if there is to return the contents of the file, otherwise it returns an error message.
- 3, the browser receives the information from the server and displays the received file or error messages.
CGI programs can be a Python script, PERL script, SHELL script, C or C ++ programs.
CGI Chart
Web server configuration and support
Before you conduct CGI programming, make sure that your Web server has been configured to support CGI and CGI handler.
Apache supports CGI configuration:
Set up the CGI directory:
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
All HTTP server to execute CGI programs are stored in a pre-configured directory. This directory is called the CGI directory, and by convention, it is named / var / www / cgi-bin directory.
CGI file extension .cgi, python can also use the .py extension.
By default, Linux server configuration running cgi-bin directory is / var / www.
If you want to specify a different directory to run CGI scripts, you can modify the httpd.conf configuration file as follows:
<Directory "/var/www/cgi-bin"> AllowOverride None Options +ExecCGI Order allow,deny Allow from all </Directory>
Add .py suffix AddHandler, so we can access the end .py python script file:
AddHandler cgi-script .cgi .pl .py
The first CGI program
We use Python to create the first CGI program called hello.py, the file is located in / var / www / cgi-bin directory, as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- print "Content-type:text/html" print # 空行,告诉服务器结束头部 print '<html>' print '<head>' print '<meta charset="utf-8">' print '<title>Hello Word - 我的第一个 CGI 程序!</title>' print '</head>' print '<body>' print '<h2>Hello Word! 我是来自本教程的第一CGI程序</h2>' print '</body>' print '</html>'
After you save the file modification hello.py, modify the file permissions to 755:
chmod 755 hello.py
The above program is displayed in the browser to access the results are as follows:
The hello.py this script is a simple Python script, the script of the first output line "Content-type: text / html" to send to the browser type and tell the browser to display the content as "text / html".
Print output with a blank line is used to tell the server end of the header information.
HTTP header
hello.py file contents in: part of the HTTP header is "Content-type text / html", it will be sent to the browser content type tells the browser files.
HTTP header format is as follows:
HTTP 字段名: 字段内容
E.g:
Content-type: text/html
The following table describes the information in the HTTP header CGI programs are often used:
head | description |
---|---|
Content-type: | MIME entity corresponding to the information request. For example: Content-type: text / html |
Expires: Date | Response date and time expired |
Location: URL | To redirect the recipient to a non-location URL request to complete the request or identification of new resources |
Last-modified: Date | Requested resource was last modified |
Content-length: N | Content-Length request |
Set-Cookie: String | Http Cookie settings |
CGI Environment Variables
All CGI programs have received the following environment variables, which played an important role in the CGI program:
variable name | description |
---|---|
CONTENT_TYPE | This value indicates that the environment variable to the MIME type of information transfer. At present, the environment variables are generally CONTENT_TYPE: application / x-www-form-urlencoded, he said that the data from the HTML form. |
CONTENT_LENGTH | If the transfer mode server and CGI program information is POST, even if the environment variable STDIN input the number of bytes that can be read valid data from the standard. This environment variable when reading the input data must be used. |
HTTP_COOKIE | COOKIE content within the client. |
HTTP_USER_AGENT | Providing information includes the version number of the client browser or other proprietary data. |
PATH_INFO | The value of this environment variable indicates the name of the CGI program immediately after the additional path information. It often appears as an argument CGI program. |
QUERY_STRING | If the transfer mode server and CGI program information is information GET, the value of this environment variable even if passed. This information is followed by the name of the CGI program, both in the middle with a question mark '?' Separator. |
REMOTE_ADDR | The value of this environment variable is the IP address of the client sends a request, for example, the above 192.168.1.67. This value is always present. And it is the need to provide the Web client to the Web server's unique identifier can be used in CGI programs to distinguish between different Web client. |
REMOTE_HOST | The value of this environment variable contains the host name of the requesting client of CGI. If it does not you want to check, you do not need to define this environment variable. |
REQUEST_METHOD | It provides a method called script. For HTTP / 1.0 protocol script only GET and POST meaningful. |
SCRIPT_FILENAME | The full path to CGI scripts |
SCRIPT_NAME | The name of the CGI script |
SERVER_NAME | This is the host name, alias, or IP address of your WEB server. |
SERVER_SOFTWARE | The value of this environment variable contains the call CGI program name and version number of the HTTP server. For example, the above value of Apache / 2.2.14 (Unix) |
Here is a simple CGI script output CGI environment variables:
#!/usr/bin/python # -*- coding: UTF-8 -*- # filename:test.py import os print "Content-type: text/html" print print "<meta charset=\"utf-8\">" print "<b>环境变量</b><br>"; print "<ul>" for key in os.environ.keys(): print "<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]) print "</ul>"
Save the above points test.py, and modify the file permissions to 755, execution results are as follows:
GET and POST methods
Browser client to the server to deliver information in two ways, both of which method is GET and POST methods.
Use the GET method of transferring data
GET method to send the encoded user information to the server, the data information is contained in the URL of the page request to number divided as follows "?":
http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2GET requests about some of the other comments:
- GET request can be cached
- GET request remains in the browser history
- GET requests can be bookmarked
- GET requests should not be used when dealing with sensitive data
- GET requests have length restrictions
- GET requests should only be used to retrieve data
Examples of simple url: GET method
The following is a simple URL, using GET method to send two parameters to hello_get.py program:
/cgi-bin/test.py?name=本教程&url=https://w3big.com
A code hello_get.py file:
#!/usr/bin/python # -*- coding: UTF-8 -*- # filename:test.py # CGI处理模块 import cgi, cgitb # 创建 FieldStorage 的实例化 form = cgi.FieldStorage() # 获取数据 site_name = form.getvalue('name') site_url = form.getvalue('url') print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2>%s官网:%s</h2>" % (site_name, site_url) print "</body>" print "</html>"
After you save the file modification hello_get.py, modify the file permissions to 755:
chmod 755 hello_get.py
Browser requests output:
Examples of simple form: GET method
The following is a two send data to the server using the GET method via an HTML form, submitted the same server script hello_get.py file, hello_get.html code is as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/hello_get.py" method="get"> 站点名称: <input type="text" name="name"> <br /> 站点 URL: <input type="text" name="url" /> <input type="submit" value="提交" /> </form> </body> </html>
By default, the cgi-bin directory can only store a script file, we will be under the test directory, modify the file permissions hello_get.html stored as 755:
chmod 755 hello_get.html
Gif presentation is as follows:
Use the POST method to pass data
Using the POST method to pass data to the server is more secure and reliable, as some sensitive information such as user passwords need to use POST to transfer data.
The following is also hello_get.py, it can also handle POST form data submitted by the browser:
#!/usr/bin/python # -*- coding: UTF-8 -*- # CGI处理模块 import cgi, cgitb # 创建 FieldStorage 的实例化 form = cgi.FieldStorage() # 获取数据 site_name = form.getvalue('name') site_url = form.getvalue('url') print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2>%s官网:%s</h2>" % (site_name, site_url) print "</body>" print "</html>"
Following is a form to submit data to the server script hello_get.py by POST method (method = "post"):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/hello_get.py" method="post"> 站点名称: <input type="text" name="name"> <br /> 站点 URL: <input type="text" name="url" /> <input type="submit" value="提交" /> </form> </body> </html>
Gif presentation is as follows:
CGI program to pass data through the checkbox
checkbox used to submit one or more option data, HTML code is as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/checkbox.py" method="POST" target="_blank"> <input type="checkbox" name="w3big" value="on" /> 本教程 <input type="checkbox" name="google" value="on" /> Google <input type="submit" value="选择站点" /> </form> </body> </html>
A code checkbox.py file:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据 if form.getvalue('google'): google_flag = "是" else: google_flag = "否" if form.getvalue('w3big'): w3big_flag = "是" else: w3big_flag = "否" print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 本教程是否选择了 : %s</h2>" % w3big_flag print "<h2> Google 是否选择了 : %s</h2>" % google_flag print "</body>" print "</html>"
Modify checkbox.py permissions:
chmod 755 checkbox.py
Browser Access Gif presentation charts:
Radio data transfer via CGI program
Radio only transfer data to a server, HTML code is as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/radiobutton.py" method="post" target="_blank"> <input type="radio" name="site" value="w3big" /> 本教程 <input type="radio" name="site" value="google" /> Google <input type="submit" value="提交" /> </form> </body> </html>
radiobutton.py script code is as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据 if form.getvalue('site'): site = form.getvalue('site') else: site = "提交数据为空" print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 选中的网站是 %s</h2>" % site print "</body>" print "</html>"
Modify radiobutton.py permissions:
chmod 755 radiobutton.py
Browser Access Gif presentation charts:
Textarea transfer data via CGI program
Textarea pass multiple rows of data to the server, HTML code is as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/textarea.py" method="post" target="_blank"> <textarea name="textcontent" cols="40" rows="4"> 在这里输入内容... </textarea> <input type="submit" value="提交" /> </form> </body> </html>
textarea.py script code is as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据 if form.getvalue('textcontent'): text_content = form.getvalue('textcontent') else: text_content = "没有内容" print "Content-type:text/html" print print "<html>" print "<head>"; print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 输入的内容是:%s</h2>" % text_content print "</body>" print "</html>"
Modify textarea.py permissions:
chmod 755 textarea.py
Browser Access Gif presentation charts:
Drop-down pass data through the CGI program.
HTML drop-down box code as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form action="/cgi-bin/dropdown.py" method="post" target="_blank"> <select name="dropdown"> <option value="w3big" selected>本教程</option> <option value="google">Google</option> </select> <input type="submit" value="提交"/> </form> </body> </html>
dropdown.py script code as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 引入 CGI 处理模块 import cgi, cgitb # 创建 FieldStorage的实例 form = cgi.FieldStorage() # 接收字段数据 if form.getvalue('dropdown'): dropdown_value = form.getvalue('dropdown') else: dropdown_value = "没有内容" print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>本教程 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 选中的选项是:%s</h2>" % dropdown_value print "</body>" print "</html>"
Modify dropdown.py permissions:
chmod 755 dropdown.py
Browser Access Gif presentation charts:
CGI is used Cookie
Http protocol in a big drawback is wrong to judge a user's identity, which give programmers a great deal of inconvenience, but appears cookie functionality made up for this deficiency.
cookie that is accessing the script while the customer through the customer's browser on the client hard disk to write data records, retrieve data when a customer visits the next script, so as to achieve the function of determining the identity, cookie commonly used in verifying identity.
cookie syntax
Http cookie is sent through the http header to achieve, he had to transfer files, header set-cookie syntax is as follows:
Set-cookie:name=name;expires=date;path=path;domain=domain;secure
- name = name: to set the value of the cookie (name can not be used ";" and "," number), when there are multiple name values ";" to separate, for example: name1 = name1; name2 = name2 ; name3 = name3.
- expires = date: cookie expiration date in the format: expires = "Wdy, DD- Mon-YYYY HH: MM: SS"
- path = path: the path set cookie support, if the path is a path, the cookie for all files and subdirectories of the directory entry into force, for example: path = "/ cgi-bin /", if the path is a file, cookie It refers to the entry into force of this file, for example: path = "/ cgi-bin / cookie.cgi".
- domain = domain: the domain name of the cookie is valid, for example: domain = "w3big.com"
- secure: If this flag is given, that the cookie can only be transmitted through SSL protocol https server.
- cookie is received by setting environment variables HTTP_COOKIE achieved, CGI programs can obtain information by retrieving the cookie variable.
Cookie settings
Cookie settings is very simple, cookie will be sent separately at http header. The following example sets the name and expires in a cookie:
#!/usr/bin/python # -*- coding: UTF-8 -*- # print 'Content-Type: text/html' print 'Set-Cookie: name="本教程";expires=Wed, 28 Aug 2016 18:30:00 GMT' print print """ <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <h1>Cookie set OK!</h1> </body> </html> """
Save the code above to cookie_set.py, and modify cookie_set.py permissions:
chmod 755 cookie_set.py
The above examples use the Set-Cookie header to set the Cookie information, options set Cookie other attributes, such as the expiration time Expires, domain Domain, Path Path. This information is provided: Before "Content-type text / html".
Retrieving Cookie Information
Cookie information retrieval page is very simple, in the CGI environment variables HTTP_COOKIE, the storage format is as follows Cookie information is stored:
key1=value1;key2=value2;key3=value3....
Here is a simple CGI program to retrieve cookie information:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 导入模块 import os import Cookie print "Content-type: text/html" print print """ <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <h1>读取cookie信息</h1> """ if 'HTTP_COOKIE' in os.environ: cookie_string=os.environ.get('HTTP_COOKIE') c=Cookie.SimpleCookie() c.load(cookie_string) try: data=c['name'].value print "cookie data: "+data+"<br>" except KeyError: print "cookie 没有设置或者已过去<br>" print """ </body> </html> """
Save the code above to cookie_get.py, and modify cookie_get.py permissions:
chmod 755 cookie_get.py
More color Gif cookie settings are as follows:
Examples of file uploads
HTML settings file to upload need to set the enctype attribute to multipart / form-data, code as follows:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <form enctype="multipart/form-data" action="/cgi-bin/save_file.py" method="post"> <p>选中文件: <input type="file" name="filename" /></p> <p><input type="submit" value="上传" /></p> </form> </body> </html>
save_file.py script file code is as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- import cgi, os import cgitb; cgitb.enable() form = cgi.FieldStorage() # 获取文件名 fileitem = form['filename'] # 检测文件是否上传 if fileitem.filename: # 设置文件路径 fn = os.path.basename(fileitem.filename) open('/tmp/' + fn, 'wb').write(fileitem.file.read()) message = '文件 "' + fn + '" 上传成功' else: message = '文件没有上传' print """\ Content-Type: text/html\n <html> <head> <meta charset="utf-8"> <title>本教程(w3big.com)</title> </head> <body> <p>%s</p> </body> </html> """ % (message,)
Save the code above to save_file.py, and modify save_file.py permissions:
chmod 755 save_file.py
More color Gif cookie settings are as follows:
If you are using Unix / Linux, you must replace the file separator at window only need to use open () statement can be:
fn = os.path.basename(fileitem.filename.replace("\\", "/" ))
File Download dialog box
We create foo.txt file in the current directory for downloading the program.
Download the file by setting the HTTP header information to implement the function code is as follows:
#!/usr/bin/python # -*- coding: UTF-8 -*- # HTTP 头部 print "Content-Disposition: attachment; filename=\"foo.txt\""; print # 打开文件 fo = open("foo.txt", "rb") str = fo.read(); print str # 关闭文件 fo.close()