我們?yōu)g覽網(wǎng)頁(yè)時(shí)可能需要把網(wǎng)頁(yè)上的內(nèi)容保存下來(lái),這時(shí)候有幾種方式可以做到:1、把重要的內(nèi)容復(fù)制出來(lái);2、對(duì)網(wǎng)頁(yè)進(jìn)行截圖保存,我們推薦過(guò)的截圖插件如印象筆記·剪藏、Full Page Screen Capture等;3、把網(wǎng)頁(yè)保存成PDF,如Adobe Acrobat。4、直接把網(wǎng)頁(yè)保存成HTML。當(dāng)然所有瀏覽器都有另存頁(yè)面為HTML 文檔的功能,不過(guò)可能會(huì)遇到一些問(wèn)題,保存后不是各種資源如JS、CSS和圖片的文件很多,就是打開后無(wú)法載入樣式表,圖片顯示不出來(lái),要把網(wǎng)頁(yè)備份起來(lái)或傳送給別人就很麻煩。本文要介紹的SingleFile是一款免費(fèi)瀏覽器擴(kuò)展,可以將完整的頁(yè)面保存到一個(gè)HTML文件中,包括所有CSS和圖片等等,讓用戶即使在一個(gè)HTML文檔中也能瀏覽完整內(nèi)容。除了單一頁(yè)面外,SingleFile還支持保存選中的部分、非固定標(biāo)簽頁(yè)或所有頁(yè)面,操作上也非常的簡(jiǎn)單易用。如果你有保存頁(yè)面的需求,可以試試這款插件。
簡(jiǎn)介
SingleFile
換流的作用就是將我們的字節(jié)流轉(zhuǎn)換成字符流
字節(jié)流是可以處理一切內(nèi)容的,包括圖片,音頻,視頻,也包括純文本,在很多系統(tǒng)和框架的底層返回給我們的都是字節(jié)流(有時(shí)候我們使用字節(jié)流處理并不方便,這就是我們?yōu)槭裁匆D(zhuǎn)換字符流的原因)
System.in,System.out都是字節(jié)流,因?yàn)槲覀冩I盤輸入還是輸出的都是字符串,所以我們可以對(duì)它進(jìn)行轉(zhuǎn)換。
在我們的底層,如果是純文本的話就涉及到一個(gè)東西是字符集。將字節(jié)轉(zhuǎn)成字符叫做解碼(在解碼的過(guò)程中就涉及到字符集的問(wèn)題,如果工程的字符集跟源頭(文件)的字符集不統(tǒng)一就會(huì)出現(xiàn)亂碼),所以這個(gè)時(shí)候我們最好可以指定字符集
從字節(jié)流到字符流的轉(zhuǎn)換
只要我們看見(jiàn)Reader都建議加一個(gè)BufferedReader
將寫入的字符編碼為字節(jié)
講一下什么使用字節(jié)流,什么時(shí)候使用字符流
其實(shí)底層都是字節(jié),我們使用字符是為了處理一些文本和字符串提高性能字符流處理的單元為2個(gè)字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個(gè)字節(jié),操作字節(jié)和字節(jié)數(shù)組。所以字符流是由Java虛擬機(jī)將字節(jié)轉(zhuǎn)化為2個(gè)字節(jié)的Unicode字符為單位的字符而成的,所以它對(duì)多國(guó)語(yǔ)言支持性比較好!如果是音頻文件、圖片、歌曲,就用字節(jié)流好點(diǎn),如果是關(guān)系到中文(文本)的,用字符流好點(diǎn) 所有文件的儲(chǔ)存是都是字節(jié)(byte)的儲(chǔ)存,在磁盤上保留的并不是文件的字符而是先把字符編碼成字節(jié),再儲(chǔ)存這些字節(jié)到磁盤。在讀取文件(特別是文本文件)時(shí),也是一個(gè)字節(jié)一個(gè)字節(jié)地讀取以形成字節(jié)序列
字節(jié)流和字符流的使用:
Java IO流中提供了兩種用于將字節(jié)流轉(zhuǎn)換為字符流的轉(zhuǎn)換流。其中InputStreamReader用于將字節(jié)輸入流轉(zhuǎn)換為字符輸入流,其中OutputStreamWriter用于將字節(jié)輸出流轉(zhuǎn)換為字符輸出流。使用轉(zhuǎn)換流可以在一定程度上避免亂碼,還可以指定輸入輸出所使用的字符集
講一下緩存流和轉(zhuǎn)換流的結(jié)合,看見(jiàn)Reader我們就可以使用緩存流提高性能
使用轉(zhuǎn)換流實(shí)現(xiàn)字節(jié)到字符的轉(zhuǎn)換以及輸入和輸出
· 節(jié)點(diǎn)流:可以從或向一個(gè)特定的地方(節(jié)點(diǎn))讀寫數(shù)據(jù)。如FileReader.
· 處理流:是對(duì)一個(gè)已存在的流的連接和封裝,通過(guò)所封裝的流的功能調(diào)用實(shí)現(xiàn)數(shù)據(jù)讀寫。如BufferedReader.處理流的構(gòu)造方法總是要帶一個(gè)其他的流對(duì)象做參數(shù)。一個(gè)流對(duì)象經(jīng)過(guò)其他流的多次包裝,稱為流的鏈接。
講一下什么是節(jié)點(diǎn)流
字符流和字節(jié)流就可以叫做節(jié)點(diǎn)流
出現(xiàn)亂碼的原因有兩種:
1.字節(jié)數(shù)不夠出現(xiàn)亂碼
2.字符集不統(tǒng)一出現(xiàn)亂碼
html文件的下載,如何使用字節(jié)流,如何使用轉(zhuǎn)換流
在java中文件的傳輸其實(shí)就是靠流來(lái)實(shí)現(xiàn)的,網(wǎng)絡(luò)流也是屬于字節(jié)流,所以我們先使用字節(jié)流
我覺(jué)得寫的時(shí)候應(yīng)該是全部都寫出來(lái)才寫的,具體debug才知道,我這里就不弄了
為什么讀取的時(shí)候亂碼,寫入的時(shí)候不亂碼
忽然一下子自己就懂了,總之寫入的時(shí)候只要講字符集設(shè)置的和源頭的文件一致就可以了
前端項(xiàng)目開發(fā)的時(shí)候,系統(tǒng)支持文件下載是前端開發(fā)中常用到的功能之一,當(dāng)用戶訪問(wèn)我們的網(wǎng)站時(shí)發(fā)現(xiàn)有自己需要的資源時(shí)可以將資源下載下來(lái)。文件下載主要有兩種形式,一種是通過(guò)文件地址下載,該文件可以存放在前端或者后端。另一種則是通過(guò)文件流下載,前端通過(guò)發(fā)送請(qǐng)求給后端并獲取后端文件流進(jìn)行下載。
download屬性:是HTML5中的a標(biāo)簽的新特性,用來(lái)規(guī)定被下載的超鏈接目標(biāo)。在a標(biāo)簽中如果沒(méi)有申明download屬性的時(shí)a標(biāo)簽的默會(huì)鏈接跳轉(zhuǎn)進(jìn)行預(yù)覽(如txt , jpg , pdf ),當(dāng)前瀏覽器不支持預(yù)覽的文件時(shí)則出現(xiàn)下載。當(dāng)申明了download屬性之后瀏覽器會(huì)對(duì)href屬性鏈接的文件進(jìn)行下載。download屬性與不支持H5的低版本瀏覽器不兼容且僅限于同源文件,如果是非同源download屬性會(huì)失效。比如引用第三方的網(wǎng)站內(nèi)容、引用前后端分離的服務(wù)器內(nèi)容、甚至本地測(cè)試引用的本地文件,download都會(huì)不起作用。如果你想測(cè)試該功能可以在本地開一個(gè)服務(wù),將文件放同一服務(wù)中測(cè)試就可以了。
直接使用a標(biāo)簽時(shí)只要在a標(biāo)簽中添加download屬性,如果是非a標(biāo)簽的話可以在出發(fā)事件的時(shí)候通過(guò)JavaScript來(lái)創(chuàng)建一個(gè)隱藏a標(biāo)簽下載,當(dāng)我們點(diǎn)擊時(shí)觸發(fā)隱藏的a標(biāo)簽下載事件。這里使用appendChild和removeChild的處理是為了兼容Firefox瀏覽器。
需要了解XMLHttpRequest可以參考文章:JavaScript實(shí)戰(zhàn)001:XMLHttpRequest使用入門,這里我利用XMLHttpRequest對(duì)象來(lái)發(fā)送請(qǐng)求,用blob類型來(lái)接受后臺(tái)發(fā)過(guò)來(lái)的二進(jìn)制類型文件。然后模擬a標(biāo)簽創(chuàng)建隱藏的下載鏈接,通過(guò)URL.createObjectURL()方法創(chuàng)建一個(gè)指向blob對(duì)象的URL地址。
iframe是HTML標(biāo)簽元素,可以用來(lái)創(chuàng)建內(nèi)聯(lián)框架。iframe提供了src屬性用來(lái)規(guī)定在 iframe 中顯示的文檔的 URL,我們可以直接將文件地址拋給iframe,也可以賦值文件流地址給iframe。功能實(shí)現(xiàn)跟a標(biāo)簽有點(diǎn)相似,創(chuàng)建一個(gè)隱藏的iframe標(biāo)簽來(lái)實(shí)現(xiàn)文件的下載功能。使用文件地址下載需要注意的是瀏覽器支持預(yù)覽的文件類型無(wú)法下載(比如圖片、PDF文檔、text文本等會(huì)直接打開文件預(yù)覽),文件流下載只需將請(qǐng)求接口賦給src屬性,iframe會(huì)自動(dòng)去請(qǐng)求該文件實(shí)現(xiàn)下載。
window.open()方法用于打開一個(gè)新的瀏覽器窗口或查找一個(gè)已命名的窗口,也可以用它來(lái)實(shí)現(xiàn)文件下載功能。而且這個(gè)比iframe更簡(jiǎn)單,直接將文件地址或者請(qǐng)求接口賦給window.open(url)方法即可實(shí)現(xiàn)文件下載功能。但是有個(gè)缺點(diǎn)就是每次下載都會(huì)打開一個(gè)新的窗口來(lái)實(shí)現(xiàn)下載(想不跳轉(zhuǎn)可以嘗試window.location.assign()方法,用于加載一個(gè)新的文檔),而且如果使用文件地址下載的是瀏覽器支持預(yù)覽的文件類型無(wú)法下載(比如圖片、PDF文檔、text文本等會(huì)直接打開文件預(yù)覽)。
form表單是個(gè)比較常用的html表簽,用戶提交用戶信息,比如常見(jiàn)的登錄、注冊(cè)界面大部分都是通過(guò)form表單進(jìn)行數(shù)據(jù)提交的。form表單所有要提交的數(shù)據(jù)都必須放在form標(biāo)簽中,method屬性定義提交的方法(有g(shù)et和post兩種提交方法),action屬性定義請(qǐng)求的地址。form標(biāo)簽中支持input、menus、textarea、fieldset、legend 和 label 等元素,通過(guò)submit向服務(wù)器提交數(shù)據(jù)。這里我創(chuàng)建了form表單和input框,input用于輸入請(qǐng)求的參數(shù),form用于提交數(shù)據(jù)請(qǐng)求。
這里提供下Django的后臺(tái)文件請(qǐng)求接口,以上文件請(qǐng)求都是基于該接口實(shí)現(xiàn)的。接收請(qǐng)求方法為GET,請(qǐng)求參數(shù)為id(數(shù)據(jù)庫(kù)存儲(chǔ)的文件id),采用FileResponse方式返回的文件流信息(具體實(shí)現(xiàn)功能可以參考文章:Django實(shí)戰(zhàn)013:各種文件下載功能實(shí)現(xiàn)詳解)。
下載的方式方法有很多,以上只是JavaScript中常見(jiàn)的幾種下載方式。其實(shí)用ajax或者axios也可以實(shí)現(xiàn)下載,但是萬(wàn)變不離其中,會(huì)JavaScript下載害怕不會(huì)別的么。以上下載方式個(gè)人覺(jué)得還是iframe比較簡(jiǎn)單方便,請(qǐng)求最好還是通過(guò)文件流來(lái)實(shí)現(xiàn),相對(duì)文件地址下載會(huì)更安全些。
更多前端技巧可以參考專欄:Vue實(shí)戰(zhàn)技巧
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。