今年國慶假期終于可以憋在家里了不用出門了,不用出去看后腦了,真的是一種享受。這么好的光陰怎么浪費,睡覺、吃飯、打豆豆這怎么可能(耍多了也煩),完全不符合我們程序員的作風,趕緊起來把文章寫完。
這篇文章比較基礎,在國慶期間的業余時間寫的,這幾天又完善了下,力求把更多的前端所涉及到的關于文件上傳的各種場景和應用都涵蓋了,若有疏漏和問題還請留言斧正和補充。
以下是本文所涉及到的知識點,break or continue ?
原理很簡單,就是根據 http 協議的規范和定義,完成請求消息體的封裝和消息體的解析,然后將二進制內容保存到文件。
我們都知道如果要上傳一個文件,需要把 form 標簽的enctype設置為multipart/form-data,同時method必須為post方法。
那么multipart/form-data表示什么呢?
multipart互聯網上的混合資源,就是資源由多種元素組成,form-data表示可以使用HTML Forms 和 POST 方法上傳文件,具體的定義可以參考RFC 7578。
multipart/form-data 結構
看下 http 請求的消息體
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次請求要上傳文件,其中boundary表示分隔符,如果要上傳多個表單項,就要使用boundary分割,每個表單項由———XXX開始,以———XXX結尾。
每一個表單項又由Content-Type和Content-Disposition組成。
Content-Disposition: form-data 為固定值,表示一個表單元素,name 表示表單元素的 名稱,回車換行后面就是name的值,如果是上傳文件就是文件的二進制內容。
Content-Type:表示當前的內容的 MIME 類型,是圖片還是文本還是二進制數據。
解析
客戶端發送請求到服務器后,服務器會收到請求的消息體,然后對消息體進行解析,解析出哪是普通表單哪些是附件。
可能大家馬上能想到通過正則或者字符串處理分割出內容,不過這樣是行不通的,二進制buffer轉化為string,對字符串進行截取后,其索引和字符串是不一致的,所以結果就不會正確,除非上傳的就是字符串。
不過一般情況下不需要自行解析,目前已經有很成熟的三方庫可以使用。
至于如何解析,這個也會占用很大篇幅,后面的文章在詳細說。
使用 form 表單上傳文件
在 ie時代,如果實現一個無刷新的文件上傳那可是費老勁了,大部分都是用 iframe 來實現局部刷新或者使用 flash 插件來搞定,在那個時代 ie 就是最好用的瀏覽器(別無選擇)。
DEMO
這種方式上傳文件,不需要 js ,而且沒有兼容問題,所有瀏覽器都支持,就是體驗很差,導致頁面刷新,頁面其他數據丟失。
HTML
<form method="post" action="http://localhost:8100" enctype="multipart/form-data">
選擇文件:
<input type="file" name="f1"/> input 必須設置 name 屬性,否則數據無法發送<br/>
<br/>
標題:<input type="text" name="title"/><br/><br/><br/>
<button type="submit" id="btn-0">上 傳</button>
</form>
復制代碼
服務端文件的保存基于現有的庫koa-body結合 koa2實現服務端文件的保存和數據的返回。
在項目開發中,文件上傳本身和業務無關,代碼基本上都可通用。
在這里我們使用koa-body庫來實現解析和文件的保存。
koa-body 會自動保存文件到系統臨時目錄下,也可以指定保存的文件路徑。
然后在后續中間件內得到已保存的文件的信息,再做二次處理。
NODE
/**
* 服務入口
*/
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: {
//設置文件的默認保存目錄,不設置則保存在系統臨時目錄下 os
uploadDir: path.resolve(__dirname, '../static/uploads')
},
multipart: true // 開啟文件上傳,默認是關閉
}));
//開啟靜態文件訪問
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 ...... ');
復制代碼
CODE
https://github.com/Bigerfe/fe-learn-code/
最近項目遇到一個說小不小說大不大的問題,輸入框要自動換行,并且高度還得自適應,我試了幾種方式,
1.input 輸入,input不能換行,上網查詢了說將css設為word-break: break-all; word-wrap:break-word;也是無效的。
2.div 設置contenteditable="true"屬性,這種方法可以實現輸入內容自動換行,并且自適應高度,但是項目需要光標從邊輸入,我試過text-align:right是無效的。所以這種方式也不行。
3.textarea,文本輸入框,想想這個應該可以了吧,文本輸入框是可以內容自動換行,可是高度怎么都是固定的啊。我還是沒解決。百度吧,終于找到解決辦法啦。
最后遇到一個光標在placeholder提示文字上面,解決辦法:#textarea::-webkit-input-placeholder{ padding-right: 4px;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#textarea {
display: block;
margin:0 auto;
overflow: hidden;
width: 550px;
font-size: 14px;
height: 18px;
line-height: 24px;
padding:2px;
text-align: right;
}
textarea {
outline: 0 none;
border-color: rgba(82, 168, 236, 0.8);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
}
</style>
</head>
<body>
<textarea id="textarea" placeholder="回復內容"></textarea>
<script>
var autoTextarea = function (elem, extra, maxHeight) {
extra = extra || 0;
var isFirefox = !!document.getBoxObjectFor || 'mozInnerScreenX' in window,
isOpera = !!window.opera && !!window.opera.toString().indexOf('Opera'),
addEvent = function (type, callback) {
elem.addEventListener ?
elem.addEventListener(type, callback, false) :
elem.attachEvent('on' + type, callback);
},
getStyle = elem.currentStyle ? function (name) {
var val = elem.currentStyle[name];
if (name === 'height' && val.search(/px/i) !== 1) {
var rect = elem.getBoundingClientRect();
return rect.bottom - rect.top -
parseFloat(getStyle('paddingTop')) -
parseFloat(getStyle('paddingBottom')) + 'px';
};
return val;
} : function (name) {
return getComputedStyle(elem, null)[name];
},
minHeight = parseFloat(getStyle('height'));
elem.style.resize = 'none';
var change = function () {
var scrollTop, height,
padding = 0,
style = elem.style;
if (elem._length === elem.value.length) return;
elem._length = elem.value.length;
if (!isFirefox && !isOpera) {
padding = parseInt(getStyle('paddingTop')) + parseInt(getStyle('paddingBottom'));
};
scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
elem.style.height = minHeight + 'px';
if (elem.scrollHeight > minHeight) {
if (maxHeight && elem.scrollHeight > maxHeight) {
height = maxHeight - padding;
style.overflowY = 'auto';
} else {
height = elem.scrollHeight - padding;
style.overflowY = 'hidden';
};
style.height = height + extra + 'px';
scrollTop += parseInt(style.height) - elem.currHeight;
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
elem.currHeight = parseInt(style.height);
};
};
addEvent('propertychange', change);
addEvent('input', change);
addEvent('focus', change);
change();
};
</script>
<script>
var text = document.getElementById("textarea");
autoTextarea(text);// 調用
</script>
</body>
</html>
HTML簡介
HTML是用來描述網頁的一種語言,它是一種超文本標記語言,由一套標記標簽組成,在制作網頁時,HTML使用標記標簽來描述網頁。
發展史
HTML:Hyper Text Markup Language超文本標記語言
超文本標記語言—在1993年6月互聯網工程工作小組工作案發布(并非標準)
HTML2.0—1995年11月作為RFC1866發布,在RFC2854于2000年6月發布之后被宣布過時。
HTML3.2—1996年1月14日,W3C推薦標準
HTML4.0—1997年12月18日,W3C推薦標準
HTML4.01(微小改進)—1999年12月24日,W3C推薦標準,2000年5月15日發布基本嚴格的HTML4.01語法,是國標標準化組織和國際電工委員會的標準
XHTML1.0—發布于2000年1月26日,是W3C推薦標準,后來經過修訂于2002年8月1日重新發布
XHTML1.1—2001年5月31日發布
XHTML2.0是W3C的工作草案,由于改動過大,學習這個新技術的成本過高而最終胎死腹中,因此,現在最常用的還是XHTML1.0標準。
目前最新的版本為HTML5,它是2004年被提出,2007年被W3C接納并成立新的HTML工作團隊,
2008年1月22日公布HTML5第一份正式草案,
2012年12月17日HTML5規范正式定稿,
2013年5月6日,HTML5.1正式草案公布。
HTML 5作為最新版本,提供了一些新的元素和一些有趣的新特性,同時也建立了一些新的規則。這些元素、特性和規則的建立,提供了許多新的網頁功能,如使用網頁實現動態渲染圖形、圖表、圖像和動畫,以及不需要安裝任何插件直接使用網頁播放視頻等。目前企業開發中也在增大使用HTML5的力度
HTML的優勢
h1~h6
源代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>標題標簽</title> </head> <body> <h1>這是一級標題</h1> <h2>這是二級標題</h2> <h3>這是三級標題</h3> <h4>這是四級標題</h4> <h5>這是五級標題</h5> <h6>這是六級標題</h6> <h7>這是七級標題</h7>效果怎么顯示不出來呢??? <h1>這是一級標題</h1> </body> </html> |
瀏覽器預覽效果
p標簽為段落標簽,br標簽為換行標簽
源代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>段落和換行標簽</title> </head> <body> <h1>北京歡迎你</h1> <p>北京歡迎你,<br>為你開天辟地</p> <p>北京歡迎你,<br/>有有勇氣就會有奇跡</p> </body> </html> |
瀏覽器預覽效果圖
hr標簽為水平線標簽
源代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>水平線標簽</title> </head> <body> <h1>漂洋過海來看你</h1> <hr> <p>為你我用了半年的積蓄,<br>漂洋過海來看你</p> <hr/> </body> </html> |
瀏覽器預覽效果圖
em為斜體標簽,strong為字體加粗標簽
源代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>字體樣式標簽</title> </head> <body> <h1>漂洋過海來看你</h1> <hr> <p>為你我用了<em>2017</em>半年的<strong><em>積蓄</em></strong>,<br> <em><strong>漂洋過海</strong></em>來看你 </p> <hr/> </body> </html> |
瀏覽器預覽效果圖
注釋使用:<!--被注釋的內容-->
大于號:> great than的縮寫
小于號:< less than的縮寫
雙引號:""
版權符號:©
空格:
源代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注釋和特殊符號</title> </head> <body> <pre> 注釋使用:<!--被注釋的內容--> 大于號:> great than的縮寫 小于號:< less than的縮寫 雙引號:"" 版權符號:© 空格: </pre> <!-- 我是被注釋的內容,我只留給你們看,不會在頁面上顯示 --> 5<10>6 <br> "我是被雙引號引起來的內容"<br> ©自由職業開發者公司<br> 我是 測試 空 格的 </body> </html> |
瀏覽器預覽效果圖
以上就是HTML的簡單入門,后續帶大家更深入的了解HTML
*請認真填寫需求信息,我們會在24小時內與您取得聯系。