不得不說,好多時間都浪費這了,MD最主要的還是浪費在tomcat運行cgi的404錯誤這,一打開http://localhost:8080/cgi-bin/xx.cgi就發生404錯誤,雖然百度下404錯誤知道是個路徑錯誤,但我這超菜鳥級別的還是猶如海底撈針,不知道從哪改。尤其是在昨天,cgi可以運行了,html表單運行不了,出來就是個空白,最後發現還是路徑錯誤。。。
第一個問題就是運行cgi的配置,總的來說百度下就知道了。
先看index.html的代碼:
<html>
<head>
<title>File Editor</title>
</head>
<body>
<form action='/cgi-bin/edit.cgi' method='POST'>
<b>File name:</b><br/>
<input type='text' name='filename'/>
<input type='submit' value='Open'/>
</form>
</body>
</html>
其中tomcat的默認路徑是 \ROOT ,而我把Index.html放到了/ROOT/WEB-INF/cgi/ 目錄中,這就是造成空白的原因,造成空白而不產生404錯誤,這說明可以訪問到index.html文件,路徑裏有這個文件,但是不能解析index.html文件,導致於空白,後來我把index.html直接放到\ROOT目錄下,發現可以訪問並解析。而cgi機制在web.xml裏的默認路徑是/ROOT/WEB-INF/cgi/,而且要訪問cgi文件,必須在url中輸入/cgi-bin/xx.cgi,因爲在cgi映射中是這樣規定的。所以我覺得/ROOT/WEB-INF/cgi/目錄中的不能運行html文件的,可以直接放到默認的ROOT根目錄下。
iindex.html大概的意思是:頁面生成一個File Editor標題,主題內容是File name:,然後一個空白標號,下面是一個需要輸入名字的文本框,接着是一個用以實現提交功能的’Open‘按鈕,並且把輸入都提交給要跳轉的頁面,而action='/cgi-bin/edit.cgi'則就是將要跳轉的頁面。
下面看看跳轉的頁面edit.cgi代碼:
print 'Content-type: text/html\n'
from os.path import join, abspath
import cgi,sys
BASE_DIR = abspath('data')
form = cgi.FieldStorage()
filename = form.getvalue('filename')
if not filename:
print 'Please enter a file name'
sys.exit()
try:
text = open(join(BASE_DIR,filename)).read()
except Exception,data:
print str(data)
print """
<html>
<head>
<title>Editing...</title>
</head>
<body>
<form action='/cgi-bin/save.cgi' method='POST'>
<b>File:</b>%s<br/>
<input type='hidden' value='%s' name='filename'/>
<b>Password:</b><br/>
<input name='password' type='password' /><br/>
<b>Text:</b><br/>
<textarea name='text' cols='40' rows='20'>%s</textarea><br/>
<input type='submit' value='Save' />
</form>
</body>
</html>
""" % (filename, filename, text)
這個跳轉頁面也遇到了一個問題,當我測試cgi文件能不能運行時,就打開了http://localhost:8080/cgi-bin/edit.cgi,我發現只會輸出一條 ’Please Enter a file name',理所當然,因爲我就沒有輸入文件名。但是當我從index.html表單跳轉到edit.cgi頁面時就出現了404,原因就是我原先的index.html中的action賦值爲‘edit.cgi’,路徑不對,計算機找不到對應的文件,後來想到cgi文件必須經過/cgi-bin/xx.cgi來訪問,所以修改後就可以跳轉了。並且你要打開的文件一定存在,而且還有路徑要求,比如我建一個空白test.txt文檔,放在
/ROOT/WEB-INF/cgi/data/目錄下,就是在cgi文件夾下再建一個data文件夾,然後放裏面即可。
edit.cgi的大概意思是:cgi.FiledStorange()是獲取表單的參數(這是是網上查到的),下面緊接着就是獲取文件名了,然後確定你輸入的文件名是否爲空,爲空則打印‘PleaseEnter a file name’,並且退出程序。下面就是一個捕捉異常的代碼,意思是打開data中你所輸入的文件名,但是如果data中根本沒有你所輸入的文件名(打開一個文件夾中不存在的文件),就會引發異常,打印 一條 說沒有該文件的字符串。如果有那就是打開了。接着下面就又是一些html代碼了,和index.html中功能差不多,不一樣的就是
<input type='hidden' value='%s' name='filename'/>是表示一個隱藏域,我不知道隱藏這個幹什麼,然後就是生成一個密碼框,他和文本框不同之處輸入的都是隱藏的,接下來就是一個高寬40*20像素的文本框 了,最後也是一個實現提交功能的按鈕‘save’,用來跳轉到save.cgi
接下來看save.cgi代碼:
print 'Content-type: text/html\n'
from os.path import join, abspath
import cgi, sha, sys
BASE_DIR = abspath('data')
form = cgi.FieldStorage()
text = form.getvalue('text')
filename = form.getvalue('filename')
password = form.getvalue('password')
if not (filename and text and password):
print 'Invalid parameters'
sys.exit()
if sha.sha(password).hexdigest() != '8843d7f92416211de9ebb963ff4ce28125932878':
print 'Invalid password'
sys.exit()
f = open(join(BASE_DIR,filename), 'w')
f.write(text)
f.close()
print 'The file has been saved.'
現在我知道那個<input type='hidden' value='%s' name='filename'/>是用來隱藏的意思了,隱藏文件名是用來傳給save.cgi。
save.cgi代碼的大概意思是:獲取上頁面傳來的文件名和密碼,還多一個獲取上頁面輸入的文本內容(text = form.getvalue('text')),然後判斷你輸入的文件名或密碼或內容是否爲空,爲空則打印 ‘Invalid parameters’,無效的參數。且推出程序。還有就是如果你輸入的密碼不對(這是事先經過sha函數生成的信息摘要),則打印‘Invalid password’,無效的密碼。
最後如果密碼對了,就打開data中且與你輸入一致的文件名,並且往此文件中寫入text傳過來的內容,關閉文件,打印 'The file has been saved.',文件被存儲了。
最後上圖: