今年國慶假期終于可以憋在家里了不用出門了,不用出去看后腦了,真的是一種享受。這么好的光陰怎么浪費,睡覺、吃飯、打豆豆這怎么可能(耍多了也煩),完全不符合我們程序員的作風(fēng),趕緊起來把文章寫完。
這篇文章比較基礎(chǔ),在國慶期間的業(yè)余時間寫的,這幾天又完善了下,力求把更多的前端所涉及到的關(guān)于文件上傳的各種場景和應(yīng)用都涵蓋了,若有疏漏和問題還請留言斧正和補充。
以下是本文所涉及到的知識點,break or continue ?
原理很簡單,就是根據(jù) http 協(xié)議的規(guī)范和定義,完成請求消息體的封裝和消息體的解析,然后將二進制內(nèi)容保存到文件。
我們都知道如果要上傳一個文件,需要把 form 標簽的enctype設(shè)置為multipart/form-data,同時method必須為post方法。
那么multipart/form-data表示什么呢?
multipart互聯(lián)網(wǎng)上的混合資源,就是資源由多種元素組成,form-data表示可以使用HTML Forms 和 POST 方法上傳文件,具體的定義可以參考RFC 7578。
multipart/form-data 結(jié)構(gòu)
看下 http 請求的消息體
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次請求要上傳文件,其中boundary表示分隔符,如果要上傳多個表單項,就要使用boundary分割,每個表單項由———XXX開始,以———XXX結(jié)尾。
每一個表單項又由Content-Type和Content-Disposition組成。
Content-Disposition: form-data 為固定值,表示一個表單元素,name 表示表單元素的 名稱,回車換行后面就是name的值,如果是上傳文件就是文件的二進制內(nèi)容。
Content-Type:表示當前的內(nèi)容的 MIME 類型,是圖片還是文本還是二進制數(shù)據(jù)。
解析
客戶端發(fā)送請求到服務(wù)器后,服務(wù)器會收到請求的消息體,然后對消息體進行解析,解析出哪是普通表單哪些是附件。
可能大家馬上能想到通過正則或者字符串處理分割出內(nèi)容,不過這樣是行不通的,二進制buffer轉(zhuǎn)化為string,對字符串進行截取后,其索引和字符串是不一致的,所以結(jié)果就不會正確,除非上傳的就是字符串。
不過一般情況下不需要自行解析,目前已經(jīng)有很成熟的三方庫可以使用。
至于如何解析,這個也會占用很大篇幅,后面的文章在詳細說。
使用 form 表單上傳文件
在 ie時代,如果實現(xiàn)一個無刷新的文件上傳那可是費老勁了,大部分都是用 iframe 來實現(xiàn)局部刷新或者使用 flash 插件來搞定,在那個時代 ie 就是最好用的瀏覽器(別無選擇)。
DEMO
這種方式上傳文件,不需要 js ,而且沒有兼容問題,所有瀏覽器都支持,就是體驗很差,導(dǎo)致頁面刷新,頁面其他數(shù)據(jù)丟失。
HTML
<form method="post" action="http://localhost:8100" enctype="multipart/form-data">
選擇文件:
<input type="file" name="f1"/> input 必須設(shè)置 name 屬性,否則數(shù)據(jù)無法發(fā)送<br/>
<br/>
標題:<input type="text" name="title"/><br/><br/><br/>
<button type="submit" id="btn-0">上 傳</button>
</form>
復(fù)制代碼
服務(wù)端文件的保存基于現(xiàn)有的庫koa-body結(jié)合 koa2實現(xiàn)服務(wù)端文件的保存和數(shù)據(jù)的返回。
在項目開發(fā)中,文件上傳本身和業(yè)務(wù)無關(guān),代碼基本上都可通用。
在這里我們使用koa-body庫來實現(xiàn)解析和文件的保存。
koa-body 會自動保存文件到系統(tǒng)臨時目錄下,也可以指定保存的文件路徑。
然后在后續(xù)中間件內(nèi)得到已保存的文件的信息,再做二次處理。
NODE
/**
* 服務(wù)入口
*/
var http = require('http');
var koaStatic = require('koa-static');
var path = require('path');
var koaBody = require('koa-body');//文件保存庫
var fs = require('fs');
var Koa = require('koa2');
var app = new Koa();
var port = process.env.PORT || '8100';
var uploadHost= `http://localhost:${port}/uploads/`;
app.use(koaBody({
formidable: {
//設(shè)置文件的默認保存目錄,不設(shè)置則保存在系統(tǒng)臨時目錄下 os
uploadDir: path.resolve(__dirname, '../static/uploads')
},
multipart: true // 開啟文件上傳,默認是關(guān)閉
}));
//開啟靜態(tài)文件訪問
app.use(koaStatic(
path.resolve(__dirname, '../static')
));
//文件二次處理,修改名稱
app.use((ctx) => {
var file = ctx.request.files.f1;//得道文件對象
var path = file.path;
var fname = file.name;//原文件名稱
var nextPath = path+fname;
if(file.size>0 && path){
//得到擴展名
var extArr = fname.split('.');
var ext = extArr[extArr.length-1];
var nextPath = path+'.'+ext;
//重命名文件
fs.renameSync(path, nextPath);
}
//以 json 形式輸出上傳文件地址
ctx.body = `{
"fileUrl":"${uploadHost}${nextPath.slice(nextPath.lastIndexOf('/')+1)}"
}`;
});
/**
* http server
*/
var server = http.createServer(app.callback());
server.listen(port);
console.log('demo1 server start ...... ');
復(fù)制代碼
CODE
https://github.com/Bigerfe/fe-learn-code/
表單的信息發(fā)送與處理過程可以簡單的進行圖示,如下圖。
以注冊會員為例,用戶在自己的電腦上打開相應(yīng)的注冊表單頁面填寫信息,完成填寫后點擊提交按鈕,也就是圖中1所示過程。
這時瀏覽器會將這些信息發(fā)送給處理這些信息的服務(wù)器,服務(wù)器上有使用類似asp或php寫成的相應(yīng)的處理程序,處理完成后,生成一個反饋信息,也就是2到3的過程。
然后服務(wù)器將處理后的信息發(fā)送給個人電腦,個人電腦在瀏覽器上通過一個新頁面來提示用戶處理結(jié)果。
這里就涉及到一個問題,一個網(wǎng)站會有針對不同用戶的信息注冊表單以及相應(yīng)的信息處理程序,比如我們注冊頭條號就有"個人"、"企業(yè)"、"媒體"和"國家機構(gòu)"的區(qū)分。如何使不同的表單找到相應(yīng)的處理程序呢?在<form>標簽中,有一個action屬性就是為這個表單信息指定處理程序的。
<form>中的action屬性
調(diào)用程序
<form>的action屬性實際上就是為表單提示處理程序所在的路徑,如果程序和頁面在一個服務(wù)器中存儲,那使用相對路徑即可,如果在其他服務(wù)器,則要使用絕對路徑。示例代碼如下:
<form action="form_action.asp" method="get">
<p>First name: <input type="text" name="fname" /></p>
<p>Last name: <input type="text" name="lname" /></p>
<input type="submit" value="Submit" />
</form>
這段代碼中的"form_action.asp"程序和這個表單頁面在一個文件夾中,故直接寫名稱即可調(diào)用。
發(fā)送郵件
action屬性除了調(diào)用程序外,也可以發(fā)送郵件,示例代碼如下:
<form action="MAILTO:someone@w3school.com.cn" method="post" enctype="text/plain">
<h3>這個表單會把電子郵件發(fā)送到 W3School。</h3>
姓名:<br />
<input type="text" name="name" value="yourname" size="20"><br />
電郵:<br /><input type="text" name="mail" value="yourmail" size="20"><br />
內(nèi)容:<br /><input type="text" name="comment" value="yourcomment" size="40"><br /><br />
<input type="submit" value="發(fā)送">
<input type="reset" value="重置">
</form>
這段代碼中。發(fā)送郵件的寫法是這樣的:action="MAILTO:someone@w3school.com.cn",通過MAILTO:告訴瀏覽器,這里要發(fā)送郵件!然后輸入相應(yīng)的郵箱地址,這樣就會把表單中的信息以郵件的形式發(fā)送到相應(yīng)的郵箱中了。
大家可以把郵箱地址改成自己的郵箱試一下,瀏覽器會讓大家選擇發(fā)送郵件的程序。如圖所示:
使用這個功能我們可以寫一個簡單的郵件發(fā)送頁面,示例代碼如下:
<form action="mailto:yourname@domain.com" method="post" enctype="text/plain">
主題:<input name="subject" type="text"><br>
抄送:<input name="cc" type="text"><br>
密送:<input name="bcc" type="text"><br>
正文:<textarea name="body"></textarea><br>
<input type="submit">
</form>
這樣的寫法大家可能會發(fā)現(xiàn)問題,即如果一個網(wǎng)站注冊用戶超過100人以后,靠這種手動輸入用戶郵箱的方法發(fā)送郵件簡直就是折磨人啊!
實際上,在網(wǎng)站中,我們會把會員或注冊用戶的郵箱存在數(shù)據(jù)庫中,通過調(diào)用數(shù)據(jù)庫中的用戶郵箱的程序語句來替換action中的具體郵箱地址即可,再通過程序,可以針對全部用戶或部分用戶進行群發(fā)信息。
其中,enctype屬性是向服務(wù)器聲明上傳信息的形式,也就是向服務(wù)器說明發(fā)送的數(shù)據(jù)到底是數(shù)字還是英文還是中文還是編程語句。專業(yè)一些的說法是"規(guī)定在發(fā)送表單數(shù)據(jù)之前如何對其進行編碼。"
全部屬性值有三個,如圖所示,大家可以簡要理解一下。
除此之外,我們還發(fā)現(xiàn)一個屬性叫做method(方法),通過上面的示例代碼可知,method屬性有兩個屬性值,一個是get一個是post,這是什么意思呢?
信息上傳的兩種方法
<form>中的method標簽即為表單信息指定相應(yīng)的發(fā)送方法。
方法有兩種,一種叫g(shù)et,這種方法通常用來發(fā)送簡短的且低安全要求的信息,特點是速度比較快。
post經(jīng)常用來發(fā)送體積較大的信息,如果發(fā)送一些對安全性要求高的信息,html的官方說明中建議使用post方法。
我個人認為,現(xiàn)階段大家能記住這兩個方法的主要特點即可。這一篇的內(nèi)容實際上也是前端學(xué)習(xí)者對服務(wù)器端的運行的了解內(nèi)容。
下面為大家附上更為專業(yè)的講解,看不懂也沒關(guān)系,盡量讀,至少能被專業(yè)詞匯洗禮一下!
method 屬性
瀏覽器使用 method 屬性設(shè)置的方法將表單中的數(shù)據(jù)傳送給服務(wù)器進行處理。共有兩種方法:POST 方法和 GET 方法。
如果采用 POST 方法,瀏覽器將會按照下面兩步來發(fā)送數(shù)據(jù)。首先,瀏覽器將與 action 屬性中指定的表單處理服務(wù)器建立聯(lián)系,一旦建立連接之后,瀏覽器就會按分段傳輸?shù)姆椒▽?shù)據(jù)發(fā)送給服務(wù)器。
在服務(wù)器端,一旦 POST 樣式的應(yīng)用程序開始執(zhí)行時,就應(yīng)該從一個標志位置讀取參數(shù),而一旦讀到參數(shù),在應(yīng)用程序能夠使用這些表單值以前,必須對這些參數(shù)進行解碼。用戶特定的服務(wù)器會明確指定應(yīng)用程序應(yīng)該如何接受這些參數(shù)。
另一種情況是采用 GET 方法,這時瀏覽器會與表單處理服務(wù)器建立連接,然后直接在一個傳輸步驟中發(fā)送所有的表單數(shù)據(jù):瀏覽器會將數(shù)據(jù)直接附在表單的 action URL 之后。這兩者之間用問號進行分隔。
一般瀏覽器通過上述任何一種方法都可以傳輸表單信息,而有些服務(wù)器只接受其中一種方法提供的數(shù)據(jù)。可以在 <form> 標簽的 method (方法)屬性中指明表單處理服務(wù)器要用方法來處理數(shù)據(jù),使 POST 還是 GET。
POST 還是 GET?
如果表單處理服務(wù)器既支持 POST 方法又支持 GET 方法,那么你該選擇哪種方法呢?下面是有關(guān)這方面的一些規(guī)律:
如果希望獲得最佳表單傳輸性能,可以采用 GET 方法發(fā)送只有少數(shù)簡短字段的小表單。
一些服務(wù)器操作系統(tǒng)在處理可以立即傳遞給應(yīng)用程序的命令行參數(shù)時,會限制其數(shù)目和長度,在這種情況下,對那些有許多字段或是很長的文本域的表單來說,就應(yīng)該采用 POST 方法來發(fā)送。
如果你在編寫服務(wù)器端的表單處理應(yīng)用程序方面經(jīng)驗不足,應(yīng)該選擇 GET 方法。如果采用 POST 方法,就要在讀取和解碼方法做些額外的工作,也許這并不很難,但是也許你不太愿意去處理這些問題。
如果安全性是個問題,那么我們建議選用 POST 方法。GET 方法將表單參數(shù)直接放在應(yīng)用程序的 URL 中,這樣網(wǎng)絡(luò)窺探者可以很輕松地捕獲它們,還可以從服務(wù)器的日志文件中進行摘錄。如果參數(shù)中包含了信用卡帳號這樣的敏感信息,就會在不知不覺中危及用戶的安全。而 POST 應(yīng)用程序就沒有安全方面的漏洞,在將參數(shù)作為單獨的事務(wù)傳輸給服務(wù)器進行處理時,至少還可以采用加密的方法。
如果想在表單之外調(diào)用服務(wù)器端的應(yīng)用程序,而且包括向其傳遞參數(shù)的過程,就要采用 GET 方法,因為該方法允許把表單這樣的參數(shù)包括進來作為 URL 的一部分。而另一方面,使用 POST 樣式的應(yīng)用程序卻希望在 URL 后還能有一個來自瀏覽器額外的傳輸過程,其中傳輸?shù)膬?nèi)容不能作為傳統(tǒng) <a> 標簽的內(nèi)容。
以上內(nèi)容來自W3school
今天的內(nèi)容結(jié)束了,這一篇內(nèi)容實踐的東西比較少,主要是閱讀與了解。
至此,HTML表單部分的講解就算告于段落了,如果您有任何疑問請給我留言,如有問題或錯誤請予以斧正!
如果您喜歡我的教程請關(guān)注我,點贊也能讓我充滿動力!
HTML序章(學(xué)習(xí)目的、對象、基本概念)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML是什么?——零基礎(chǔ)自學(xué)網(wǎng)頁制作
第一個HTML頁面如何寫?——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML頁面中head標簽有啥用?——零基礎(chǔ)自學(xué)網(wǎng)頁制作
初識meta標簽與SEO——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML中的元素使用方法1——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML中的元素使用方法2——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML元素中的屬性1——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML元素中的屬性2(路徑詳解)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
使用HTML添加表格1(基本元素)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
使用HTML添加表格2(表格頭部與腳部)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
使用HTML添加表格3(間距與顏色)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
使用HTML添加表格4(行顏色與表格嵌套)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
16進制顏色表示與RGB色彩模型——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML中的塊級元素與內(nèi)聯(lián)元素——零基礎(chǔ)自學(xué)網(wǎng)頁制作
初識HTML中的<div>塊元素——零基礎(chǔ)自學(xué)網(wǎng)頁制作
在HTML頁面中嵌入其他頁面的方法——零基礎(chǔ)自學(xué)網(wǎng)頁制作
封閉在家學(xué)網(wǎng)頁制作!為頁面嵌入PDF文件——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML表單元素初識1——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML表單元素初識2——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML表單3(下拉列表、多行文字輸入)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML表單4(form的action、method屬性)——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML列表制作講解——零基礎(chǔ)自學(xué)網(wǎng)頁制作
為HTML頁面添加視頻、音頻的方法——零基礎(chǔ)自學(xué)網(wǎng)頁制作
音視頻格式轉(zhuǎn)換神器與html視頻元素加字幕——零基礎(chǔ)自學(xué)網(wǎng)頁制作
HTML中使用<a>標簽實現(xiàn)文本內(nèi)鏈接——零基礎(chǔ)自學(xué)網(wǎng)頁制作
什么是表單呢?當前端想要提交數(shù)據(jù)給后端,怎么搞?那么在前端開發(fā)中,表單是常用的手段,比如常見的場景有:登錄框、賬號注冊頁、主機信息錄入CMDB等等場景都是需要表單。那么在本篇中,筆者除了講一些基本的知識點,還會再結(jié)合后端的方式來演示如何接收表單提交的數(shù)據(jù)。希望這些小小的演示可以起到拋磚引玉的效果。
構(gòu)建表單,主要是通過from元素,我們先來一個最簡單的小栗子,看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>主機信息錄入CMDB</h3>
<form>
<label for="hostname">主機名:</label><br>
<input type="text" id="hostname" name="hostname"><br>
<label for="ipaddr">IP地址:</label><br>
<input type="text" id="ipaddr" name="ipaddr"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
通上面的小栗子可以知道,form表單的主要通途是用于收集用戶的輸入。在from表單里面,還包含著各種不同類型的input元素,比如我們上面小栗子中用到的文本(text)、提交按鈕(submit)。
input元素是表單里最重要的元素,它有很多type屬性,下面我們來總結(jié)下:
類型描述text文本輸入radio單選按鈕checkbox提交按鈕submit提交按鈕button可單擊按鈕
在上面小栗子中,除了input元素之外,不知道大家注意label元素沒有。label元素的主要用途是為input元素定義標簽,且用for屬性和input元素的id屬性進行綁定呢。
什么是單選按鈕?就是在多個選項中,你只能選其中1個,不能多選。下面我們看個小栗子,看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>問答題1(單選):某站長,工作經(jīng)驗不足1年,僅從互聯(lián)網(wǎng)收集學(xué)習(xí)資料制定學(xué)習(xí)路線售賣盈利,從道德層面角度分析是否有問題?</h3>
<form>
<input type="radio" id="i1" name="problem" value="yes">
<label for="i1">有</label>
<input type="radio" id="i2" name="problem" value="no">
<label for="i2">沒有</label>
<input type="radio" id="i3" name="problem" value="not_clear">
<label for="i3">不清楚</label>
</form>
<h3>問答題2(單選):實際工作經(jīng)驗不足1年的人員折騰的學(xué)習(xí)資料您覺得是否對你有幫助?</h3>
<form>
<input type="radio" id="w1" name="problem" value="yes">
<label for="w1">有</label>
<input type="radio" id="w2" name="problem" value="no">
<label for="w2">沒有</label>
<input type="radio" id="w3" name="problem" value="not_clear">
<label for="w3">不清楚</label>
</form>
</body>
</html>
效果如下圖:
上面的小栗子中,出了兩道問答題,均為單選題。那么,類似的需求都是可以使用輸入類型為radio來實現(xiàn)需要使用單選按鈕的場景。
什么是復(fù)選框?復(fù)選框就是可以選擇多個選項,當需要多選的時候,使用復(fù)選框輸入類型就對了。看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>問答題1(單選):某站長,工作經(jīng)驗不足1年,僅從互聯(lián)網(wǎng)收集學(xué)習(xí)資料制定學(xué)習(xí)路線售賣盈利,從道德層面角度分析是否有問題?</h3>
<form>
<input type="checkbox" id="i1" name="problem" value="yes">
<label for="i1">有</label>
<input type="checkbox" id="i2" name="problem" value="no">
<label for="i2">沒有</label>
<input type="checkbox" id="i3" name="problem" value="not_clear">
<label for="i3">不清楚</label><br>
<input type="submit" value="提交">
</form>
<h3>問答題2(單選):實際工作經(jīng)驗不足1年的人員折騰的學(xué)習(xí)資料您覺得是否對你有幫助?</h3>
<form>
<input type="checkbox" id="w1" name="problem" value="yes">
<label for="w1">有</label>
<input type="checkbox" id="w2" name="problem" value="no">
<label for="w2">沒有</label>
<input type="checkbox" id="w3" name="problem" value="not_clear">
<label for="w3">不清楚</label><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
上面的小栗子中,實現(xiàn)復(fù)選框的輸入類型是checkbox,這個是重點哦!
當有數(shù)據(jù)要提交給后端的時候怎么搞?如果后端是API服務(wù),可以給它提交json。如果是前端頁面,就需要通過構(gòu)建表單來獲取用戶的輸入。基于表單提交數(shù)據(jù)給后端,怎么提交?需要一個可以點擊的提交按鈕,那這個按鈕怎么來?先看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form>
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
輸入類型為submit,說明它就是提交按鈕,注意上面代碼type="submit"了嗎?
在之前的例子中,前端表單需要將數(shù)據(jù)提交給后端,除了需要一個提交按鈕外,還需要action屬性。當點擊提交按鈕后,表單的數(shù)據(jù)該發(fā)到后端的哪個url進行處理,就是定義在action屬性中。接下來,我們結(jié)合前端和后端直接來個小實戰(zhàn),后端代碼用Python的Flask框架。
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼:
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=["GET", "POST"])
def ttropsstack():
args = request.args
print 'ip addr is: %s' % args.get('ip')
return 'ok'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
前端和后端的代碼寫完后,我們接下來看看效果
輸入IP地址后,點擊提交
這個ok是后端返回的
后端接收到數(shù)據(jù)后,啥也沒做,只是做了簡單打印
這個小栗子很簡單,通過這個小栗子,是不是對action屬性的用法有了進一步的理解呢?
method屬性的用途是指定提交數(shù)據(jù)的http方法,通常有2個,get和post。接下來我們在上個小栗子的基礎(chǔ)上做個小改造,看下面代碼
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="get">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼:
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=["POST"])
def ttropsstack():
args = request.args
print 'ip addr is: %s' % args.get('ip')
return 'ok'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
當前端輸入數(shù)據(jù)后,提交表單時,直接告訴你這是不允許的方法
在這個例子中,是因為前端的表單了指定了method為get請求,而后端接收數(shù)據(jù)的method規(guī)定了需要post請求,故所以出現(xiàn)這個問題。
下面我們改造一下后端代碼:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
print request.get_data(as_text=True)
return 'ok'
else:
return '提交數(shù)據(jù)需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
前端表單中的method還是保持get請求,再次提交,后端的返回如下:
看到了嗎?后端判斷前端過來的請求是get還是post,很顯然,前端過來的請求是get,并且返回了非常友好的提示。
接下來我們繼續(xù)改造一下前端的代碼,將請求修改為post,代碼如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼也稍微改造一下,改變接收前端數(shù)據(jù)的方法
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
a = request.form
print a.get('ip')
print type(a)
return 'ok'
else:
return '提交數(shù)據(jù)需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
輸入IP地址,并點擊提交
提交后,后端給前端返回了ok
接下來看下后端,后端啥也沒做,就獲取到表單的數(shù)據(jù),然后打印了數(shù)據(jù),并且打印了下數(shù)據(jù)類型
好了,關(guān)于前端的action屬性和Method屬性就講到這里了。為了講解action和method,還結(jié)合了后端的一丟丟知識,前端和后端的知識點以后都會慢慢講到哈!
先來個前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="opslist">運維開發(fā)應(yīng)掌握的技能:</label>
<select id="opslist" name="opslist">
<option value="python">Python語言</option>
<option value="go">Go語言</option>
<option value="shell">Shell語言</option>
<option value="database">數(shù)據(jù)庫</option>
<option value="frontend">前端</option>
<option value="linux">Linux</option>
<option value="network">網(wǎng)絡(luò)</option>
<option value="storage">存儲</option>
</select>
<input type="submit">
</form>
</body>
</html>
后端代碼:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
a = request.form
print a.get('opslist')
return 'ok'
else:
return '提交數(shù)據(jù)需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
在下拉框中選擇“Go語言”,并提交
后端啥也沒干,就只做了打印
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術(shù)棧社區(qū)主頁</title>
</head>
<body>
<h2>彩虹運維技術(shù)棧社區(qū),公眾號ID:TtrOpsStack</h2>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="opslist">運維開發(fā)應(yīng)掌握的技能:</label>
<select id="opslist" name="opslist" size="6" multiple>
<option value="python">Python語言</option>
<option value="go">Go語言</option>
<option value="shell">Shell語言</option>
<option value="database">數(shù)據(jù)庫</option>
<option value="frontend">前端</option>
<option value="linux">Linux</option>
<option value="network">網(wǎng)絡(luò)</option>
<option value="storage">存儲</option>
</select>
<input type="submit">
</form>
</body>
</html>
上述前端代碼中,是使用multiple屬性來實現(xiàn)選擇多個值。
后端代碼的打印方式稍微做了些許調(diào)整:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
data = request.get_data()
print data
return 'ok'
else:
return '提交數(shù)據(jù)需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
按住ctrl或者shift鍵可進行多選
后端打印的效果圖下圖:
關(guān)于表單基礎(chǔ)知識點的講解就這么愉快的結(jié)束了,關(guān)于更多表單的元素、輸入屬性、輸入類型可自行查閱和實戰(zhàn),筆者因時間有限就不一一演示。感謝您的閱讀,望多多關(guān)注我們、點贊、轉(zhuǎn)發(fā)!
本文轉(zhuǎn)載于(喜歡的盆友關(guān)注我們):https://mp.weixin.qq.com/s/L-Msv39JrF7AzRx4K1OLjA
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。