注:下方基礎題若是對你來你說不能很好的回答,請點擊上方詳細資料連接,系統學習這個知識點 javascript
JavaScript 提供了一個內部數據結構,用來描述對象的屬性,控制它的行爲,好比該屬性是否可寫、可遍歷等等。這個內部數據結構稱爲屬性描述對象
(attributes object)php
configurable(可配置性)
返回一個布爾值,決定了是否能夠修改屬性描述對象。也就是說,configurable爲false時,value、writable、enumerable和configurable都不能被修改了。css
var obj = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
enumerable: false,
configurable: false
});
Object.defineProperty(obj, 'p', {value: 2})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {writable: true})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {enumerable: true})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {configurable: true})
// TypeError: Cannot redefine property: p
複製代碼
上面代碼中,obj.p的configurable爲false。而後,改動value、writable、enumerable、configurable,結果都報錯。html
注意,writable只有在false改成true會報錯,true改成false是容許的。html5
var obj = Object.defineProperty({}, 'p', {
writable: true,
configurable: false
});
Object.defineProperty(obj, 'p', {writable: false})
// 修改爲功
至於value,只要writable和configurable有一個爲true,就容許改動。
var o1 = Object.defineProperty({}, 'p', {
value: 1,
writable: true,
configurable: false
});
Object.defineProperty(o1, 'p', {value: 2})
// 修改爲功
var o2 = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
configurable: true
});
Object.defineProperty(o2, 'p', {value: 2})
// 修改爲功
複製代碼
另外,writable爲false時,直接目標屬性賦值,不報錯,但不會成功。java
var obj = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
configurable: false
});
obj.p = 2;
obj.p // 1
複製代碼
上面代碼中,obj.p的writable爲false,對obj.p直接賦值不會生效。若是是嚴格模式,還會報錯。node
可配置性決定了目標屬性是否能夠被刪除(delete)。es6
var obj = Object.defineProperties({}, {
p1: { value: 1, configurable: true },
p2: { value: 2, configurable: false }
});
delete obj.p1 // true
delete obj.p2 // false
obj.p1 // undefined
obj.p2 // 2
複製代碼
上面代碼中,obj.p1的configurable是true,因此能夠被刪除,obj.p2就沒法刪除。正則表達式
接下來就不寫問題了,若是以上問題你沒有很好的答上來,就能夠點開連接開學了,嘿嘿json
注:下方基礎題若是對你來你說不能很好的回答,請點擊上方詳細資料連接,系統學習這個知識點
/(.)b(.)\1b\2/.test("abcabc") // true
複製代碼
\1
表示第一個括號匹配的內容(即a),\2
表示第二個括號匹配的內容(即c)。'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1')
// "world hello"
複製代碼
replace方法的第二個參數可使用美圓符號$
,用來指代所替換的內容。
var s = 'aaa';
s.match(/a+/) // ["aaa"]
s.match(/a+?/) // ["a"]
複製代碼
上面爲何不同呢,由於兩次+
以後有個?
,這是開啓非貪婪模式的標記。
除了非貪婪模式的加號,還有非貪婪模式的星號(*)和非貪婪模式的問號(?)。
var r = /x/g;
var s = '_x_x';
r.lastIndex = 4;
r.test(s) // false
複製代碼
注意,使用組匹配時,不宜同時使用g
修飾符,不然match方法不會捕獲分組的內容。
var m = 'abcabc'.match(/(.)b(.)/g);
m // ['abc', 'abc']
複製代碼
能夠看到,捕獲組沒有捕獲分組內容。可是match不加g
模式的時候,能捕獲第一次遇見的捕獲組內容
var m = 'abcabc'.match(/(.)b(.)/);
m
// ['abc', 'a', 'c']
複製代碼
(?:x)
稱爲非捕獲組(Non-capturing group),表示不返回該組匹配的內容,即匹配的結果中不計入這個括號。
var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]
複製代碼
上面代碼中的模式,一共使用了兩個括號。其中第一個括號是非捕獲組,因此最後返回的結果中沒有第一個括號,只有第二個括號匹配的內容。
x(?=y)
稱爲先行斷言(Positive look-ahead),x
只有在y
前面才匹配,y
不會被計入返回結果。好比,要匹配後面跟着百分號的數字,能夠寫成/\d+(?=%)/
。
「先行斷言」中,括號裏的部分是不會返回的。
var m = 'abc'.match(/b(?=c)/);
m // ["b"]
複製代碼
上面的代碼使用了先行斷言,b在c前面因此被匹配,可是括號對應的c不會被返回。
x(?!y)
稱爲先行否認斷言(Negative look-ahead),x
只有不在y
前面才匹配,y不會被計入返回結果。好比,要匹配後面跟的不是百分號的數字,就要寫成/\d+(?!%)/
/\d+(?!\.)/.exec('3.14')
// ["14"]
複製代碼
上面代碼中,正則表達式指定,只有不在小數點前面的數字纔會被匹配,所以返回的結果就是14。
「先行否認斷言」中,括號裏的部分是不會返回的。
var m = 'abd'.match(/b(?!c)/);
m // ['b']
複製代碼
上面的代碼使用了先行否認斷言,b不在c前面因此被匹配,並且括號對應的d不會被返回。
使用new命令時,它後面的函數依次執行下面的步驟。
函數內部可使用new.target
屬性。若是當前函數是new命令調用,new.target指向當前函數,不然爲undefined。
function f() {
console.log(new.target === f);
}
f() // false
new f() // true
複製代碼
構造函數做爲模板,能夠生成實例對象。可是,有時拿不到構造函數,只能拿到一個現有的對象。咱們但願以這個現有的對象做爲模板,生成新的實例對象,這時就可使用Object.create()
方法。
var person1 = {
name: '張三',
age: 38,
greeting: function() {
console.log('Hi! I\'m ' + this.name + '.'); } }; var person2 = Object.create(person1); person2.name // 張三 person2.greeting() // Hi! I'm 張三.
複製代碼
上面代碼中,對象person1是person2的模板,後者繼承了前者的屬性和方法。
// 例如:
// HTML 代碼以下
// <button id="btn">點擊</button>
var btn = document.getElementById('btn');
btn.addEventListener(
'click',
function (e) {
console.log(this.id);
},
false
);
複製代碼
上面的代碼裏,this
指向的是觸發事件的那個元素節點
dblclick
:在同一個元素上雙擊鼠標時觸發。contextmenu
:按下鼠標右鍵時(上下文菜單出現前)觸發,或者按下「上下文菜單鍵」時觸發。MouseEvent.clientX
屬性返回鼠標位置相對於瀏覽器窗口左上角的水平座標(單位像素)MouseEvent.screenX
屬性返回鼠標位置相對於屏幕左上角的水平座標(單位像素)MouseEvent.offsetX
屬性返回鼠標位置與目標節點左側的padding邊緣的水平距離(單位像素)圖示以下:
MouseEvent.getModifierState
方法返回一個布爾值,表示有沒有按下特定的功能鍵。它的參數是一個表示功能鍵的字符串。
document.addEventListener('click', function (e) {
console.log(e.getModifierState('CapsLock'));
}, false);
複製代碼
TouchList
對象,對於touchstart
事件, 這個 TouchList
對象列出在這次事件中新增長的觸點。touchmove
事件,列出和上一次事件相比較,發生了變化的觸點。對於touchend
,列出離開觸摸平面的觸點(這些觸點對應已經不接觸觸摸平面的手指)。touchend這裏要特別注意,touches和targetTouches只存儲接觸屏幕的觸點,要獲取觸點最後離開的狀態要使用changedTouches。
綁定在拖拽目標
事件名 | 描述 |
---|---|
dragstart | 當用戶開始拖拽一個元素或者一個文本選取區塊的時觸發 |
drag | 當用戶正在拖拽一個元素或者一個文本選取區塊的時觸發 |
dragend | 當用戶結束拖拽一個元素或者一個文本選取區塊的時觸發。(如放開鼠標按鍵或按下鍵盤的 escap 鍵) |
綁定在放置目標
事件名 | 描述 |
---|---|
dragenter | 當用戶開始拖拽一個元素或者一個文本選取區塊的時觸發 |
dragover | 當用戶正在拖拽一個元素或者一個文本選取區塊的時觸發 |
dragleave | 當用戶結束拖拽一個元素或者一個文本選取區塊的時觸發。(如放開鼠標按鍵或按下鍵盤的 escap 鍵) |
drop | 當一個元素或文字選取區塊被放置至一個有效的放置目標時觸發。 |
不會
DataTransfer.dropEffect
屬性用來設置放下(drop)
被拖拉節點時的效果,會影響到拖拉通過相關區域時鼠標的形狀。 例如:target.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = 'copy';
});
複製代碼
DataTransfer.effectAllowed
屬性設置本次拖拉中容許的效果。例如:source.addEventListener('dragstart', function (e) {
e.dataTransfer.effectAllowed = 'move';
});
target.addEventListener('dragover', function (e) {
ev.dataTransfer.dropEffect = 'move';
});
複製代碼
主要是用到DataTransfer.setData()
和DataTransfer.getData()
方法, 例如
document.addEventListener('dragstart', function (event) {
// 被拖拉節點的背景色變透明
event.dataTransfer.setData('data',this.nodeName);
}, false);
document.addEventListener('drop', function( event ) {
// 防止事件默認行爲(好比某些元素節點上能夠打開連接),
event.preventDefault();
console.log(event.dataTransfer.getData('data'))
}, false);
複製代碼
正常的網頁加載流程是這樣的。
緣由是 JavaScript 代碼能夠修改 DOM,因此必須把控制權讓給它,不然會致使複雜的線程競賽的問題
若是外部腳本加載時間很長(一直沒法完成下載),那麼瀏覽器就會一直等待腳本下載完成,形成網頁長時間失去響應,瀏覽器就會呈現「假死」狀態,這被稱爲「阻塞效應」。
爲了不這種狀況,較好的作法是<script>標籤都放在頁面底部
css的加載和解析不會阻塞html的解析,但會阻塞渲染。
不一樣的瀏覽器有不一樣的渲染引擎。
渲染引擎處理網頁,一般分紅四個階段。
以上四步並不是嚴格按順序執行,每每第一步還沒完成,第二步和第三步就已經開始了。因此,會看到這種狀況:網頁的 HTML 代碼還沒下載完,但瀏覽器已經顯示出內容了。
渲染樹轉換爲網頁佈局,稱爲佈局流(flow)
;佈局顯示到頁面的這個過程,稱爲繪製(paint)
。它們都具備阻塞效應,而且會耗費不少時間和計算資源。
頁面生成之後,腳本操做和樣式表操做,都會觸發重流(reflow)
和重繪(repaint)
。用戶的互動也會觸發重流和重繪,好比設置了鼠標懸停(a:hover)效果、頁面滾動、在輸入框中輸入文本、改變窗口大小等等。
重流
和重繪
並不必定一塊兒發生,重流
必然致使重繪
,重繪
不必定須要重流
。好比改變元素顏色,只會致使重繪,而不會致使重流;改變元素的佈局,則會致使重繪和重流。
早期,瀏覽器內部對 JavaScript 的處理過程以下:
逐行解釋將字節碼轉爲機器碼,是很低效的。爲了提升運行速度,現代瀏覽器改成採用「即時編譯」(Just In Time compiler,縮寫 JIT),即字節碼只在運行時編譯,用到哪一行就編譯哪一行,而且把編譯結果緩存(inline cache)。一般,一個程序被常常用到的,只是其中一小部分代碼,有了緩存的編譯結果,整個程序的運行速度就會顯著提高。
不一樣瀏覽器對 Cookie 數量和大小的限制,是不同的。通常來講,單個域名設置的 Cookie 不該超過30個,每一個 Cookie 的大小不能超過4KB。超過限制之後,Cookie 將被忽略,不會被設置 。
瀏覽器的同源政策規定,兩個網址只要域名相同和端口相同,就能夠共享 Cookie(參見《同源政策》一章)。注意,這裏不要求協議相同。也就是說,example.com 設置的 Cookie,能夠被https://example.com讀取。
Expires
屬性指定一個具體的到期時間,到了指定時間之後,瀏覽器就再也不保留這個 Cookie。它的值是 UTC 格式,可使用Date.prototype.toUTCString()
進行格式轉換。Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
複製代碼
Max-Age
屬性:指定從如今開始 Cookie 存在的秒數,好比60 * 60 * 24 * 365(即一年)。過了這個時間之後,瀏覽器就再也不保留這個 Cookie。
若是同時指定了Expires
和Max-Age
,那麼Max-Age
的值將優先生效。
若是Set-Cookie
字段沒有指定Expires
或Max-Age
屬性,那麼這個 Cookie 就是 Session Cookie,即它只在本次對話存在,一旦用戶關閉瀏覽器,瀏覽器就不會再保留這個 Cookie
Secure
屬性指定瀏覽器只有在加密協議 HTTPS 下,才能將這個 Cookie 發送到服務器。該屬性只是一個開關,不須要指定值。若是通訊是 HTTPS 協議,該開關自動打開。
HttpOnly
屬性指定該 Cookie 沒法經過 JavaScript 腳本拿到,主要是document.cookie
屬性、XMLHttpRequest
對象和 Request API
都拿不到該屬性。
目前,若是非同源,共有三種行爲受到限制
(1) 沒法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB。
(2) 沒法接觸非同源網頁的 DOM。
(3) 沒法向非同源地址發送 AJAX 請求(能夠發送,但瀏覽器會拒絕接受響應)
複製代碼
postMessage
是html5引入的API,postMessage()
方法容許來自不一樣源的腳本採用異步方式進行有效的通訊,能夠實現跨文本文檔,多窗口,跨域消息傳遞.多用於窗口間數據通訊,這也使它成爲跨域通訊的一種有效的解決方案。
舉一個postMessage跨域通訊的案例,並介紹其API
父窗體建立跨域iframe併發送信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<iframe src="http://127.0.0.1:9090/b.html" name="postIframe" onload="messageLoad()"></iframe>
<script>
function messageLoad(){
var url = "http://127.0.0.1:9090";
window.postIframe.postMessage("給我tsort的信息",url); //發送數據
}
window.onmessage = function(e){
e = e || event;
console.log(e.data); //接收b返回的數據,在控制檯有兩次輸出
}
</script>
</body>
</html>
複製代碼
子窗體接收信息並處理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
window.onmessage = function(e){
e = e || event;
alert(e.data); //當即彈出a發送過來的數據
e.source.postMessage("好的,請稍等三秒!",e.origin); //當即回覆a
var postData = {name:"tsrot",age:24};
var strData = JSON.stringify(postData); //json對象轉化爲字符串
setTimeout(function(){
e.source.postMessage(strData,e.origin);
},3000); //3秒後向a發送數據
}
</script>
</body>
</html>
複製代碼
只要同時知足如下兩大條件,就屬於簡單請求。
1)請求方法是如下三種方法之一。
HEAD
GET
POST
複製代碼
2)HTTP 的頭信息不超出如下幾種字段。
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
複製代碼
添加一個Origin字段。說明本次請求來自哪一個域(協議 + 域名 + 端口)
若是Origin
指定的源,不在許可範圍內,服務器會返回一個正常的 HTTP 迴應。瀏覽器發現,這個迴應的頭信息沒有包含Access-Control-Allow-Origin
字段(詳見下文),就知道出錯了,從而拋出一個錯誤,被XMLHttpRequest
的onerror
回調函數捕獲。注意,這種錯誤沒法經過狀態碼識別,由於 HTTP 迴應的狀態碼有多是200。
若是Origin
指定的域名在許可範圍內,服務器返回的響應,會多出幾個頭信息字段。
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
複製代碼
CORS
請求默認不包含 Cookie 信息(以及 HTTP 認證信息等),這是爲了下降 CSRF 攻擊的風險。Access-Control-Allow-Credentials
字段,告訴瀏覽器能夠發送 Cookie。預檢請求(preflight)
。舉例:
var url = 'http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();
複製代碼
上面代碼中,HTTP 請求的方法是PUT
,而且發送一個自定義頭信息X-Custom-Header
。
瀏覽器發現,這是一個非簡單請求,就自動發出一個「預檢」請求,要求服務器確承認以這樣請求。下面是這個「預檢」請求的 HTTP 頭信息。
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
複製代碼
「預檢」請求用的請求方法是OPTIONS,表示這個請求是用來詢問的。頭信息裏面,關鍵字段是Origin
,表示請求來自哪一個源。
除了Origin
字段,「預檢」請求的頭信息包括兩個特殊字段。
(1)Access-Control-Request-Method
複製代碼
該字段是必須的,用來列出瀏覽器的 CORS 請求會用到哪些 HTTP 方法,上例是PUT。
(2)Access-Control-Request-Headers
複製代碼
該字段是一個逗號分隔的字符串,指定瀏覽器 CORS 請求會額外發送的頭信息字段,上例是X-Custom-Header。
預檢請求(preflight)
。服務器收到「預檢」請求之後,檢查了Origin
、Access-Control-Request-Method
和Access-Control-Request-Headers
字段之後,確認容許跨源請求,就能夠作出迴應。
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
複製代碼
History.pushState()方法用於在歷史中添加一條記錄。
window.history.pushState(state, title, url)
複製代碼
該方法接受三個參數,依次爲:
popstate
事件。該事件觸發時,該對象會傳入回調函數。也就是說,瀏覽器會將這個對象序列化之後保留在本地,從新載入這個頁面的時候,能夠拿到這個對象。若是不須要這個對象,此處能夠填null。var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
複製代碼
此API不會跳轉網頁。
會觸發popstate 事件 使用方法以下
window.addEventListener('popstate', function(event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
});
複製代碼
分號(;)
,逗號(,)
,斜槓(/)
,問號(?)
,冒號(:)
,at(@)
,&
,等號(=)
,加號(+)
,美圓符號($)
,井號(#)
a-z
,A-Z
,0-9
,連詞號(-)
,下劃線(_)
,點(.)
,感嘆號(!)
,波浪線(~)
,星號(*)
,單引號(')
,圓括號(())
除了以上字符,其餘字符出如今 URL 之中都必須轉義,規則是根據操做系統的默認編碼,將每一個字節轉爲百分號(%)加上兩個大寫的十六進制字母。
JavaScript 提供四個 URL 的編碼/解碼方法。
一、 encodeURI()
encodeURI()方法用於轉碼整個 URL。它的參數是一個字符串,表明整個 URL。它會將元字符和語義字符以外的字符,都進行轉義。
encodeURI('http://www.example.com/q=春節')
// "http://www.example.com/q=%E6%98%A5%E8%8A%82"
複製代碼
二、encodeURIComponent()
encodeURIComponent()方法用於轉碼 URL 的組成部分,會轉碼除了語義字符以外的全部字符,即元字符也會被轉碼。因此,它不能用於轉碼整個 URL。它接受一個參數,就是 URL 的片斷。
encodeURIComponent('春節')
// "%E6%98%A5%E8%8A%82"
encodeURIComponent('http://www.example.com/q=春節')
// "http%3A%2F%2Fwww.example.com%2Fq%3D%E6%98%A5%E8%8A%82"
複製代碼
上面代碼中,encodeURIComponent()會連 URL 元字符一塊兒轉義,因此若是轉碼整個 URL 就會出錯。
三、decodeURI() 四、decodeURIComponent()
3和4,都是1,2的逆運算
var url = new URL('http://www.example.com:4097/path/a.html?x=111#part1');
url.href
// "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
url.pathname
// "/path/a.html"
url.search
// "?x=111"
複製代碼
經常使用的靜態方法有
我本身常常會用這個API作本地圖片預覽。以下案例
<body>
<div id="display" />
<input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)">
<script>
var div = document.getElementById('display');
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var img = document.createElement('img');
console.log(window.URL.createObjectURL(files[i]))
img.src = window.URL.createObjectURL(files[i]);
div.appendChild(img);
}
}
</script>
</body>
複製代碼
注意,每次使用URL.createObjectURL方法,都會在內存裏面生成一個 URL 實例。若是再也不須要該方法生成的 URL 字符串,爲了節省內存,可使用URL.revokeObjectURL()方法釋放這個實例。
URL.revokeObjectURL方法用來釋放URL.createObjectURL方法生成的 URL 實例。它的參數就是URL.createObjectURL方法返回的 URL 字符串。
下面爲上一段的示例加上URL.revokeObjectURL()。
var div = document.getElementById('display');
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(files[i]);
div.appendChild(img);
img.onload = function() {
window.URL.revokeObjectURL(this.src);
}
}
}
複製代碼
Blob構造函數接受兩個參數。第一個參數是數組,成員是字符串或二進制對象,表示新生成的Blob實例對象的內容;第二個參數是可選的,是一個配置對象,目前只有一個屬性type,它的值是一個字符串,表示數據的 MIME 類型,默認是空字符串。
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
var myBlob = new Blob(htmlFragment, {type : 'text/html'});
複製代碼
例子以下:
var obj = { hello: 'world' };
var blob = new Blob([ JSON.stringify(obj) ], {type : 'application/json'});
複製代碼
File
對象表明一個文件,用來讀寫文件信息。它繼承了 Blob
對象,或者說是一種特殊的 Blob
對象,全部可使用 Blob
對象的場合均可以使用它。 下面代碼中,file是用戶選中的第一個文件,它是 File 的實例。
// HTML 代碼以下
// <input id="fileItem" type="file">
var file = document.getElementById('fileItem').files[0];
file instanceof File // true
複製代碼
FileReader
對象用於讀取File
對象或Blob
對象所包含的文件內容。
瀏覽器原生提供一個FileReader構造函數,用來生成 FileReader 實例。
var reader = new FileReader();
複製代碼
經常使用的FileReader 有如下的實例屬性
下面是監聽load事件的一個例子。
// HTML 代碼以下
// <input type="file" onchange="onChange(event)">
function onChange(event) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target.result)
};
reader.readAsText(file);
}
複製代碼
FileReader 比較重要的實例方法。
result
屬性將返回一個 Data URL
格式(Base64 編碼
)的字符串,表明文件內容。對於圖片文件,這個字符串能夠用於<img>
元素的src
屬性。注意,這個字符串不能直接進行 Base64 解碼,必須把前綴data:*/*;base64
,從字符串裏刪除之後,再進行解碼。Blob
實例,第二個參數是可選的,表示文本編碼,默認爲 UTF-8
。下面是一個例子。
/* HTML 代碼以下
<input type="file" onchange="previewFile()">
<img src="" height="200">
*/
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener('load', function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
複製代碼
Blob
構造函數接受兩個參數。第一個參數是數組,成員是字符串或二進制對象,表示新生成的Blob
實例對象的內容;第二個參數是可選的,是一個配置對象,目前只有一個屬性type
,它的值是一個字符串,表示數據的MIME
類型,默認是空字符串。
案例以下:
var formData = new FormData();
// 設置某個控件的值
formData.set('username', '張三');
formData.get('username') // "張三"
formData.set('username', '張三');
formData.append('username', '李四');
formData.get('username') // "張三"
formData.getAll('username') // ["張三", "李四"]
formData.append('userpic[]', myFileInput.files[0], 'user1.jpg');
formData.append('userpic[]', myFileInput.files[1], 'user2.jpg');
複製代碼
表單可以用四種編碼,向服務器發送數據。編碼格式由表單的enctype屬性決定。
(1)GET 方法
若是表單使用GET方法發送數據,enctype屬性無效。
<form
action="register.php"
method="get"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
複製代碼
數據將以 URL 的查詢字符串發出。
?foo=bar&baz=The%20first%20line.%0AThe%20second%20line.
複製代碼
(2)application/x-www-form-urlencoded
若是表單用POST方法發送數據,並省略enctype屬性,那麼數據以application/x-www-form-urlencoded格式發送(由於這是默認值)。
<form
action="register.php"
method="post"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
複製代碼
發送的 HTTP 請求以下。
Content-Type: application/x-www-form-urlencoded
foo=bar&baz=The+first+line.%0D%0AThe+second+line.%0D%0A
複製代碼
上面代碼中,數據體裏面的%0D%0A表明換行符(\r\n)。
(3)text/plain
若是表單使用POST方法發送數據,enctype屬性爲text/plain,那麼數據將以純文本格式發送。
<form
action="register.php"
method="post"
enctype="text/plain"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
複製代碼
發送的 HTTP 請求以下。
Content-Type: text/plain
foo=bar
baz=The first line.
The second line.
複製代碼
(4)multipart/form-data
若是表單使用POST方法,enctype屬性爲multipart/form-data,那麼數據將以混合的格式發送。
<form
action="register.php"
method="post"
enctype="multipart/form-data"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
複製代碼
發送的 HTTP 請求以下。
Content-Type: multipart/form-data; boundary=---------------------------314911788813839
-----------------------------314911788813839
Content-Disposition: form-data; name="foo"
bar
-----------------------------314911788813839
Content-Disposition: form-data; name="baz"
The first line.
The second line.
-----------------------------314911788813839--
複製代碼
這種格式也是文件上傳的格式。