Python CGI 프로그래밍
CGI란
NCSA는 현재 NCSA에서 관리하는 CGI를 다음과 같이 정의합니다.
CGI(Common Gateway Interface), 공통 게이트웨이 인터페이스입니다. 프로그램은 HTTP 서버와 같은 서버에서 실행되어 클라이언트 HTML 페이지와의 인터페이스를 제공합니다.
웹 탐색
CGI의 작동 방식을 더 잘 이해하기 위해 웹 페이지의 링크나 URL을 클릭하는 과정부터 시작할 수 있습니다.
1. 브라우저를 사용하여 URL에 접속하고 HTTP 웹 서버에 연결합니다.
2. 웹 서버는 요청 정보를 받은 후 URL을 구문 분석하여 해당 파일이 서버에 존재하는지 확인하고, 파일의 내용을 반환합니다. 그렇지 않으면 오류 메시지가 반환됩니다.
3. 브라우저는 서버로부터 정보를 받아 수신된 파일이나 오류 메시지를 표시합니다.
CGI 프로그램은 Python 스크립트, PERL 스크립트, SHELL 스크립트, C 또는 C++ 프로그램 등이 될 수 있습니다.
CGI 아키텍처 다이어그램
웹 서버 지원 및 구성
CGI 프로그래밍을 하기 전에 다음 사항을 확인하세요. 웹 서버는 CGI를 지원하며 CGI 처리기가 구성되어 있습니다.
Apache는 CGI 구성을 지원합니다.
CGI 디렉터리 설정:
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
모든 HTTP 서버 실행 CGI 프로그램은 미리 구성된 디렉터리에 저장됩니다. 이 디렉토리를 CGI 디렉토리라고 하며 관례적으로 이름은 /var/www/cgi-bin입니다.
CGI 파일의 확장자는 .cgi이며, 파이썬에서도 .py 확장자를 사용할 수 있습니다.
기본적으로 Linux 서버가 실행되도록 구성된 cgi-bin 디렉터리는 /var/www입니다.
CGI 스크립트를 실행하기 위해 다른 디렉터리를 지정하려면 다음과 같이 httpd.conf 구성 파일을 수정할 수 있습니다.
<Directory "/var/www/cgi-bin"> AllowOverride None Options +ExecCGI Order allow,deny Allow from all </Directory>
우리가 액세스할 수 있도록 AddHandler에 .py 접미사를 추가하세요. .py로 끝나는 python 스크립트 파일:
AddHandler cgi-script .cgi .pl .py
첫 번째 CGI 프로그램
Python을 사용하여 첫 번째 CGI 프로그램을 만들며 파일 이름은 hello.py이고 파일은 다음과 같습니다. /var/에 위치 www/cgi-bin 디렉터리의 내용은 다음과 같습니다.
#!/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! 我是来自php中文网的第一CGI程序</h2>' print '</body>' print '</html>'
파일을 저장한 후 hello.py를 수정하고 파일 권한을 755로 수정합니다.
chmod 755 hello.py
위 프로그램은 브라우저에서 액세스할 때 다음 결과를 표시합니다.
이 hello.py 스크립트는 간단한 Python 스크립트입니다. "Content-type: text/html" 스크립트가 브라우저로 전송되어 브라우저에 표시되는 콘텐츠 유형이 "text/html"임을 알려줍니다.
print를 사용하여 빈 줄을 출력하여 서버에 헤더 정보를 끝내도록 지시합니다.
HTTP 헤더
hello.py 파일 콘텐츠의 "Content-type: text/html"은 HTTP 헤더의 일부이며 브라우저에 전송되어 이를 알립니다. 브라우저 서버 파일의 콘텐츠 유형입니다.
HTTP 헤더의 형식은 다음과 같습니다.
HTTP 字段名: 字段内容
예:
Content-type: text/html
다음 표는 CGI 프로그램에서 HTTP 헤더에 일반적으로 사용되는 정보를 소개합니다.
头 | 描述 |
---|---|
Content-type: | 请求的与实体对应的MIME信息。例如: Content-type:text/html |
Expires: Date | 响应过期的日期和时间 |
Location: URL | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 |
Last-modified: Date | 请求资源的最后修改时间 |
Content-length: N | 请求的内容长度 |
Set-Cookie: String | 设置Http Cookie |
CGI 환경 변수
모든 CGI 프로그램은 CGI 프로그램에서 중요한 역할을 하는 다음과 같은 환경 변수를 받습니다.
变量名 | 描述 |
---|---|
CONTENT_TYPE | 这个环境变量的值指示所传递来的信息的MIME类型。目前,环境变量CONTENT_TYPE一般都是:application/x-www-form-urlencoded,他表示数据来自于HTML表单。 |
CONTENT_LENGTH | 如果服务器与CGI程序信息的传递方式是POST,这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。 |
HTTP_COOKIE | 客户机内的 COOKIE 内容。 |
HTTP_USER_AGENT | 提供包含了版本数或其他专有数据的客户浏览器信息。 |
PATH_INFO | 这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。 |
QUERY_STRING | 如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号'?'分隔。 |
REMOTE_ADDR | 这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。 |
REMOTE_HOST | 这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。 |
REQUEST_METHOD | 提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。 |
SCRIPT_FILENAME | CGI脚本的完整路径 |
SCRIPT_NAME | CGI脚本的的名称 |
SERVER_NAME | 这是你的 WEB 服务器的主机名、别名或IP地址。 |
SERVER_SOFTWARE | 这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix) |
다음은 CGI 환경 변수를 출력하는 간단한 CGI 스크립트입니다.
#!/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>"
위의 내용을 test.py로 저장하고, 파일 권한을 755로 수정합니다. 실행 결과는 다음과 같습니다.
GET 및 POST 방식
브라우저 클라이언트는 GET 방식과 POST 방식 두 가지 방식으로 서버에 정보를 전송합니다.
GET 방식으로 데이터 전송
GET 방식은 인코딩된 사용자 정보를 서버로 전송합니다. 데이터 정보는 요청한 페이지의 URL에 "?"로 구분되어 포함됩니다.
http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2GET 요청에 대한 기타 참고 사항:
GET 요청은 캐시될 수 있습니다
GET 요청은 브라우저 기록에 남아 있습니다
GET 요청은 북마크에 추가할 수 있습니다
민감한 데이터를 처리할 때는 GET 요청을 사용하면 안 됩니다
GET 요청 길이 제한이 있습니다
GET 요청은 데이터 검색에만 사용해야 합니다
간단한 URL 예: GET 메서드
다음 GET 메소드를 사용하여 hello_get.py 프로그램에 두 개의 매개변수를 보내는 간단한 URL입니다:
/cgi-bin/test.py?name=php中文网&url=http://www.php.cn
다음은 hello_get.py 파일의 코드입니다:
#!/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>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2>%s官网:%s</h2>" % (site_name, site_url) print "</body>" print "</html>"
저장 후 hello_get 수정 py에서 파일 권한을 755로 수정합니다:
chmod 755 hello_get.py
브라우저 요청 출력 결과:
간단한 형식 예: GET 메서드
아래 GET 메소드를 사용하여 두 개의 데이터를 서버로 보내는 HTML 형식입니다. 제출된 서버 스크립트도 hello_get.html 코드는 다음과 같습니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</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>
기본적으로. , cgi-bin 디렉토리만 저장할 수 있습니다. 스크립트 파일의 경우 hello_get.html을 test 디렉토리에 저장하고 파일 권한을 755로 수정합니다.
chmod 755 hello_get.html
Gif 데모는 다음과 같습니다.
POST 방식을 사용하여 데이터를 전송합니다
POST 방식을 사용하여 서버에 데이터를 전송하는 것이 더 안전하고 신뢰할 수 있습니다. 사용자 비밀번호와 같은 일부 민감한 정보는 POST를 사용해야 합니다. 데이터를 전송합니다.
다음은 브라우저에서 제출한 POST 폼 데이터도 처리할 수 있는 hello_get.py입니다.
#!/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>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2>%s官网:%s</h2>" % (site_name, site_url) print "</body>" print "</html>"
다음은 POST 메서드를 통한 폼입니다(method="post" ) 서버 스크립트 hello_get.py에 데이터를 제출합니다:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</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 데모는 다음과 같습니다.
CGI 프로그램을 통해 체크박스 데이터 전달
체크박스는 하나 이상의 옵션 데이터를 제출하는 데 사용됩니다. HTML 코드는 다음과 같습니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/checkbox.py" method="POST" target="_blank"> <input type="checkbox" name="php" value="on" /> php中文网 <input type="checkbox" name="google" value="on" /> Google <input type="submit" value="选择站点" /> </form> </body> </html>
다음은 checkbox.py 파일의 코드입니다.
#!/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('php'): php_flag = "是" else: php_flag = "否" print "Content-type:text/html" print print "<html>" print "<head>" print "<meta charset=\"utf-8\">" print "<title>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> php中文网是否选择了 : %s</h2>" % php_flag print "<h2> Google 是否选择了 : %s</h2>" % google_flag print "</body>" print "</html>"
Modify checkbox .py 권한:
chmod 755 checkbox.py
브라우저 액세스 Gif 데모 이미지:
CGI 프로그램을 통해 라디오 데이터 전송
라디오는 하나의 데이터만 서버로 전송하며, HTML 코드는 다음과 같습니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/radiobutton.py" method="post" target="_blank"> <input type="radio" name="site" value="php" /> php中文网 <input type="radio" name="site" value="google" /> Google <input type="submit" value="提交" /> </form> </body> </html>
radiobutton.py 스크립트 코드는 다음과 같습니다.
#!/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>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 选中的网站是 %s</h2>" % site print "</body>" print "</html>"
radiobutton .py 권한 수정:
chmod 755 radiobutton.py
브라우저 액세스 Gif 데모 이미지:
CGI 프로그램을 통해 Textarea 데이터 전송
Textarea는 여러 메시지를 서버 행 데이터로 전송합니다. HTML 코드는 다음과 같습니다:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</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 스크립트 코드는 다음과 같습니다:
#!/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>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 输入的内容是:%s</h2>" % text_content print "</body>" print "</html>"
textarea.py 수정:
chmod 755 textarea.py
브라우저 액세스 Gif 데모 이미지:
CGI 프로그램을 통해 드롭다운 데이터를 전달합니다.
HTML 드롭다운 상자 코드는 다음과 같습니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <form action="/cgi-bin/dropdown.py" method="post" target="_blank"> <select name="dropdown"> <option value="php" selected>php中文网</option> <option value="google">Google</option> </select> <input type="submit" value="提交"/> </form> </body> </html>
dropdown.py 스크립트 코드는 다음과 같습니다.
#!/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>php中文网 CGI 测试实例</title>" print "</head>" print "<body>" print "<h2> 选中的选项是:%s</h2>" % dropdown_value print "</body>" print "</html>"
dropdown.py 권한 수정:
chmod 755 dropdown.py
브라우저 Gif 데모 이미지 방문:
CGI에서 쿠키 사용
http 프로토콜의 큰 단점은 판단하지 않는다는 것입니다. 사용자의 신원은 프로그래머에게 큰 불편을 안겨줍니다. 쿠키 기능의 등장으로 이러한 단점이 보완되었습니다.
쿠키는 고객이 스크립트에 접속할 때 고객의 브라우저를 통해 고객의 하드디스크에 기록되는 데이터를 쓰는 것입니다. , 신원 식별 기능을 달성하기 위해 다음 번에 고객이 스크립트에 액세스할 때 데이터 정보가 검색됩니다. 쿠키는 신원 확인에 자주 사용됩니다.
쿠키 구문
http 쿠키는 파일 전송보다 빠른 http 헤더를 통해 전송됩니다. 헤더의 set-cookie 구문은 다음과 같습니다.
Set-cookie:name=name;expires=date;path=path;domain=domain;secure
name=name: 쿠키 값을 설정해야 합니다(name은 ";" 및 ","을 사용할 수 없음). 다수 ";"을 사용하여 이름 값을 구분합니다(예: name1=name1;name2=name2;name3=name3).
expires=date: 쿠키 유효 기간, 형식:expires="Wdy,DD-Mon-YYYY HH:MM:SS"
path=path: path가 경로인 경우 쿠키가 여기에 위치합니다. 모든 파일과 하위 디렉터리에 유효합니다(예: path="/cgi-bin/"). path가 파일인 경우 쿠키는 이 파일에 유효합니다(예: path="/cgi-bin/cookie). cgi".
domain=domain: 쿠키에 유효한 도메인 이름(예: domain="www.php.cn"
<🎜) >secure: 이 플래그가 제공되면 쿠키는 SSL 프로토콜의 https 서버를 통해서만 전달될 수 있음을 의미합니다.
- 쿠키 수신은 환경 변수 HTTP_COOKIE를 설정하여 이루어집니다. CGI 프로그램은 이 변수를 검색하여 쿠키 정보를 얻을 수 있습니다.
쿠키 설정
쿠키 설정은 매우 간단합니다. 쿠키는 http 헤더에 별도로 전송됩니다. 다음 예에서는 쿠키에 이름을 설정하고 만료됩니다.
#!/usr/bin/python # -*- coding: UTF-8 -*- # print 'Content-Type: text/html' print 'Set-Cookie: name="php中文网";expires=Wed, 28 Aug 2016 18:30:00 GMT' print print """ <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</title> </head> <body> <h1>Cookie set OK!</h1> </body> </html> """
위 코드를 cookie_set.py에 저장하고 cookie_set.py 권한을 수정합니다.
chmod 755 cookie_set.py
위 예에서는 Set- 쿠키 헤더 정보 쿠키 정보를 설정하기 위해 만료 시간, 도메인 이름, 경로 등 쿠키의 다른 속성을 선택적 옵션에 설정합니다. 이 정보는 "Content-type:text/html" 앞에 설정됩니다.
쿠키 정보 검색
쿠키 정보 검색 페이지는 매우 간단합니다. 쿠키 정보는 CGI 환경 변수 HTTP_COOKIE에 저장됩니다.
key1=value1;key2=value2;key3=value3....
다음은 쿠키 정보를 검색하는 간단한 CGI 프로그램입니다.
#!/usr/bin/python # -*- coding: UTF-8 -*- # 导入模块 import os import Cookie print "Content-type: text/html" print print """ <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</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> """
위 코드를 cookie_get.py에 저장하고 cookie_get.py 권한을 수정합니다.
chmod 755 cookie_get.py
위 쿠키 설정 색상 Gif
파일 업로드 예시
파일 업로드를 위한 HTML 설정 양식에서 enctype 속성을 으로 설정해야 합니다. multipart/form-data 코드는 다음과 같습니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>php中文网(php.cn)</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 스크립트 파일 코드는 다음과 같습니다.
#!/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>php中文网(php.cn)</title> </head> <body> <p>%s</p> </body> </html> """ % (message,)
위 코드를 save_file.py에 저장하고 수정합니다. save_file.py 권한:
chmod 755 save_file.py
위 쿠키 설정 색상 Gif는 다음과 같습니다.
사용하는 시스템이 Unix/Linux인 경우 반드시 파일 구분 기호를 바꾸십시오. 창에서는 open( ) 문만 사용해야 합니다:
fn = os.path.basename(fileitem.filename.replace("\", "/" ))
파일 다운로드 대화 상자
먼저 현재 디렉터리에 foo.txt 파일을 만듭니다. 프로그램을 다운로드하기 위해.
파일 다운로드는 HTTP 헤더 정보를 설정하여 이루어집니다. 함수 코드는
#!/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()