整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaWeb實現文件上傳與下載

          JavaWeb實現文件上傳與下載

          . 增強HttpServletResponse對象

          1. 實現一個增強的HttpServletResponse類,需要繼承javax.servlet.http.HttpServletRequestWrapper類,通過重寫自己需要增強的方法來實現(這種模式就叫做裝飾者模式),使用該增強類在加上過濾器就可以實現無編碼轉換處理代碼。

          public class MyRequest extends HttpServletRequestWrapper{
          	private HttpServletRequest req;
          	public MyRequest(HttpServletRequest request) {
          		super(request);
          		req=request;
          	}
          	@Override
          	public String getParameter(String name) {
          		//解決編碼問題,無論是post還是get請求,都不需要在業務代碼中對編碼再處理
          		String method=req.getMethod();
          		if("get".equalsIgnoreCase(method)){
          			try {
          				String str=req.getParameter(name);
          				byte[] b=str.getBytes("iso8859-1");
          				String newStr=new String(b, "utf-8");
          				return newStr;
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}else if("post".equalsIgnoreCase(method)){
          			try {
          				req.setCharacterEncoding("utf-8");
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}
          		//絕對不能刪除此行代碼,因為此行代碼返回的就是編碼之后的數據
          		return super.getParameter(name);
          	}
          }
          

          在過濾器中應用

          public class FilterTest4 implements Filter {
          	@Override
          	public void init(FilterConfig filterConfig) throws ServletException {}
          	@Override
          	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          			throws IOException, ServletException {
          		//生成增強的HttpServletRequest對象
          		HttpServletRequest req=(HttpServletRequest) request;
          		MyRequest myReq=new MyRequest(req);
          		//將增強的HttpServletRequest對象傳入過濾器執行鏈中,在后面傳入的request對象都會是增強的HttpServletRequest對象
          		chain.doFilter(myReq, response);
          		
          	}
          	@Override
          	public void destroy() {}
          }
          

          2. 文件上傳原理過程

          1. JavaWeb中實現文件上傳:

          • 客戶端:HTML頁面需要一個<form>表單,且必須設置表單的enctype屬性值為"multipart/form-data",以及method屬性值為"post"(因為get方式不支持大量數據提交);表單里有一個<input type="file" name="">的標簽,且name屬性值必須指定。
          <html>
           <head>
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <form action="" method="post" enctype="multipart/form-data">
           <input type="text" name="name">
           	請選擇文件:<input type="file" name="upload">
           	<input type="submit" value="上傳">
           </form>
           </body>
          </html>
          
          • 服務端:主要進行IO讀寫操作。必須導入commons-fileupload和commons-io兩個jar包,可以通過請求request對象的getInputStream獲得一個流來讀取請求中的文件數據,但是如果客戶端上傳多個文件時,就會很麻煩,所以提供了commons-fileupload和commons-io兩個jar包來更方便的實現文件上傳。
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.util.List;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.commons.fileupload.FileItem;
          import org.apache.commons.fileupload.FileUploadException;
          import org.apache.commons.fileupload.disk.DiskFileItemFactory;
          import org.apache.commons.fileupload.servlet.ServletFileUpload;
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		/**
          		 * 1. 創建磁盤文件項工廠類 DiskFileItemFactory
          		 * 2. 創建核心解析Request類 ServletFileUpload
          		 * 3. 開始解析Request對象中的數據,并返回一個List集合
          		 * 4. List中包含表單中提交的內容
          		 * 5. 遍歷集合,獲取內容
          		 */
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems=upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				//有可能是普通文本項,比如<input type="text">標簽提交上來的字符串
          				//也有可能是<input type="submit" value="上傳">上傳的文件
          				//文件項與普通項有不同的API來處理
          				//首先判斷是普通文本項還是文件項,
          				if(item.isFormField()){
          					//true表示普通文本項
          					//獲取文本項的name屬性值
          					String name=item.getFieldName();
          					//獲取對應的文本
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					//false表示文件項
          					//先獲取文件名稱
          					String name=item.getName();
          					//獲取文件項的輸入流
          					InputStream in=item.getInputStream();
          					//獲取服務器端文件存儲的目標磁盤路徑
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					//獲取輸出流,輸出到本地文件中
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					//寫入數據
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          

          注意:在文件上傳時,會將form表單的屬性enctype屬性值為"multipart/form-data",當提交到服務端后,無法使用 req.getParameter(name) 方法來獲取到內容,只有通過上面的方法來獲取文本項。

          2. 文件上傳相關核心類:

          • DiskFileItemFactory:相關API如下
          • public DiskFileItemFactory():無參構造器
          • public DiskFileItemFactory(int sizeThreshold, File repository):構造器,sizeThreshold設置緩沖區大小,默認10240 byte;repository表示如果過緩沖區空間小于上傳文件空間,那么會生成臨時文件,repository就是指定該臨時文件的保存路徑,如果過未上傳完成就中斷,繼續上傳時就可以通過這個臨時文件來繼續上傳。
          • public void setSizeThreshold(int sizeThreshold):設置緩沖區大小
          • public void setRepository(File repository):指定該臨時文件的保存路徑
          //改進上面的文件上傳代碼,添加一個臨時文件
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		fac.setSizeThreshold(1024*1024);//設置緩沖區為1mb
          		//設置臨時文件的本地磁盤存儲路徑
          		File repository=new File(getServletContext().getRealPath("/temp"));
          		fac.setRepository(repository);
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems=upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				if(item.isFormField()){
          					String name=item.getFieldName();
          					String value=item.getString();
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					String name=item.getName();
          					InputStream in=item.getInputStream();
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          
          • ServletFileUpload:相關API如下
          • public static final boolean isMultipartContent( HttpServletRequest request) :判斷表單提交上來的數據內容是否是multipart類型的數據,即 form表單的 enctype="multipart/form-data",是則返回true,否則返回false
          • public List /* FileItem */ parseRequest(HttpServletRequest request):解析request對象,返回一個泛型為FileItem 的List集合
          • public void setFileSizeMax(long fileSizeMax):設置單個文件的空間大小的最大值
          • public void setSizeMax(long sizeMax):設置所有文件空間大小之和的最大值
          • public void setHeaderEncoding(String encoding):解決上傳文件名的亂碼問題
          • public void setProgressListener(ProgressListener pListener):上傳時的進度條。
          • FileItem:封裝表單中提交的數據
          • boolean isFormField():判斷當前FileItem對象是表單中提交的文本數據項,還是文件數據項
          • String getFieldName():獲取文本項類型FileItem對象的name屬性值,即相當于表單中的 <input type="text" name="name">
          • String getString( String encoding ):獲取文本項類型FileItem對象的value值,可以指定編碼格式,也可以省略encoding不寫
          • String getName():應用于文件項類型的FileItem對象,用于獲取文件的名稱,包括后綴名
          • InputStream getInputStream():獲取輸入流
          • void delete():刪除臨時緩存文件(在輸入以及輸出流關閉后執行)

          3. 實現多文件上傳(需要js技術):主要是更改jsp頁面,通過js代碼來添加多個文件進行上傳,服務器代碼無需更改

          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%>
          <%
          String path=request.getContextPath();
          String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
          %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
           <head>
           <base href="<%=basePath%>">
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <script type="text/javascript">
           	function run(){
           		var div=document.getElementById("divId");
           		 div.innerHTML+="<div><input type='file' name='upload'><input type='button' value='刪除' onclick='del(this)'></div>"
           	}
           	function del(presentNode){
           		var div=document.getElementById("divId");
           		div.removeChild(presentNode.parentNode);
           	}
           </script>
           <div>
           	多文件上傳<br/>
           <form action="/Servlet/upload" method="post" enctype="multipart/form-data">
           	<input type="button" value="添加" onclick="run()"><br/>
           	<div id="divId">
           	
           	</div>
           	
           	<input type="submit" value="上傳">
           </form>
           </div>
           </body>
          </html>
          

          4. 關于文件上傳的一些問題:

          • 文件重名可能會產生覆蓋效果,可以在處理文件名時生成一個唯一的文件名
          • 如果所有的文件都儲存在一個文件夾中,會導致文件夾下文件過多,可以一個用戶一個文件夾,或者利用算法目錄分離等方法。

          3. 文件下載

          1. 傳統文件下載方式有超鏈接下載或者后臺程序下載兩種方式。通過超鏈接下載時,如果瀏覽器可以解析,那么就會直接打開,如果不能解析,就會彈出下載框;而后臺程序下載就必須通過兩個響應頭和一個文件的輸入流。

          2. 后臺程序下載:

          • 兩個響應頭:
          • Content-Type:其值有比如 text/html;charset=utf-8
          • Content-Disposition:其值為 attachment;filename=文件名 以附件形式打開
          • 流:需要獲取文件的輸入流,然后通過response對象的輸出流輸出到客戶端。

          .NodeJS簡介

          1.1 了解NodeJS

          簡單的說 Node.js 就是運行在服務端的 JavaScript。Node.js 是一個基于Chrome JavaScript 運行時建立的一個平臺。 Node.js是一個事件驅動I/O服務端JavaScript環境,基于Google的V8引擎,V8引擎執行Javascript的速度非常快,性能非常好。

          1.2 NodeJS安裝

          (我們現在使用的版本是8.9.4)

          選安裝目錄進行安裝

          • 默認即可
          • 測試
          • 在命令提示符下輸入命令
          node -v

          會顯示當前node的版本號

          2.快速入門

          2.1 控制臺輸出

          我們現在做個最簡單的小例子,演示如何在控制臺輸出,在e盤創建文件夾nodedemo ,創建文本文件demo1.js,代碼內容

          我們在命令提示符下輸入命令node demo1.js ,結果如下:

          2.2 使用函數

          我們剛才的例子非常簡單,咱們這里再看一下函數的使用:

          我們在命令提示符下輸入命令node demo2.js ,結果如下:

          2.3 模塊化編程

          創建demo3_1.js

          創建demo3_2.js

          2.4 創建web服務器

          創建demo4.js

          http為node內置的web模塊,我們在命令提示符下輸入命令 node demo4.js ,結果如下:

          心情是不是很激動呢?

          Ctrl+c 終止運行。

          2.5 理解服務端渲染

          我們創建demo5.js ,將上邊的例子寫成循環的形式

          我們在命令提示符下輸入命令node demo5.js ,在瀏覽器測試結果

          我們右鍵"查看源代碼"

          這里我們發現,并沒有我們寫的for循環語句,而是直接的10條Hello World ,這就說明這個循環是在服務端完成的,而非瀏覽器(客戶端)來完成。這與我們原來的JSP很是相似。實際中這些數據有可能由node直接讀取數據庫,或是通過ajax訪問其它網絡資源獲取

          2.6 接收參數

          創建demo6.js

          我們在命令提示符下輸入命令nodedemo6.js ,在瀏覽器測試結果

          3.總結

          本次主要講解了NodeJS在window環境下的安裝及使用。通過本篇文章希望大家可以掌握NodeJS中函數基本使用、了解什么是模塊化,如何創建web服務器以及理解什么是服務器端渲染。

          ode.js 特點


          1、單線程

          在Java、PHP或者.net等服務器端語言中,會為每一個客戶端連接創建一個新的線程。而每個線程需要耗費大約2MB內存。也就是說,理論上,一個8GB內存的服務器可以同時連接的最大用戶數為4000個左右。要讓Web應用程序支持更多的用戶,就需要增加服務器的數量,而Web應用程序的硬件成本當然就上升了。

          Node.js不為每個客戶連接創建一個新的線程,而僅僅使用一個線程。當有用戶連接了,就觸發一個內部事件,通過非阻塞I/O、事件驅動機制,讓Node.js程序宏觀上也是并行的。使用Node.js,一個8GB內存的服務器,可以同時處理超過4萬用戶的連接。

          另外,單線程帶來的好處,操作系統完全不再有線程創建、銷毀的時間開銷。

          壞處,就是一個用戶造成了線程的崩潰,整個服務都崩潰了,其他人也崩潰了。

          2、非阻塞I/O

          例如,當在訪問數據庫取得數據的時候,需要一段時間。在傳統的單線程處理機制中,在執行了訪問數據庫代碼之后,整個線程都將暫停下來,等待數據庫返回結果,才能執行后面的代碼。也就是說,I/O阻塞了代碼的執行,極大地降低了程序的執行效率。

          由于Node.js中采用了非阻塞型I/O機制,因此在執行了訪問數據庫的代碼之后,將立即轉而執行其后面的代碼,把數據庫返回結果的處理代碼放在回調函數中,從而提高了程序的執行效率。

          當某個I/O執行完畢時,將以事件的形式通知執行I/O操作的線程,線程執行這個事件的回調函數。為了處理異步I/O,線程必須有事件循環,不斷的檢查有沒有未處理的事件,依次予以處理。

          阻塞模式下,一個線程只能處理一項任務,要想提高吞吐量必須通過多線程。而非阻塞模式下,一個線程永遠在執行計算操作,這個線程的CPU核心利用率永遠是100%。所以,這是一種特別有哲理的解決方案:與其人多,但是好多人閑著;還不如一個人玩命,往死里干活兒。

          3、事件驅動 event-driven

          在Node中,客戶端請求建立連接,提交數據等行為,會觸發相應的事件。在Node中,在一個時刻,只能執行一個事件回調函數,但是在執行一個事件回調函數的中途,可以轉而處理其他事件(比如,又有新用戶連接了),然后返回繼續執行原事件的回調函數,這種處理機制,稱為“事件環”機制。

          Node.js底層是C++(V8也是C++寫的)。底層代碼中,近半數都用于事件隊列、回調函數隊列的構建。用事件驅動來完成服務器的任務調度,這是鬼才才能想到的。針尖上的舞蹈,用一個線程,擔負起了處理非常多的任務的使命。

          單線程,單線程的好處,減少了內存開銷,操作系統的內存換頁。

          如果某一個事情,進入了,但是被I/O阻塞了,所以這個線程就阻塞了。

          非阻塞I/O, 不會傻等I/O語句結束,而會執行后面的語句。

          非阻塞就能解決問題了么?比如執行著小紅的業務,執行過程中,小剛的I/O回調完成了,此時怎么辦??

          事件機制,事件環,不管是新用戶的請求,還是老用戶的I/O完成,都將以事件方式加入事件環,等待調度。

          說是三個特點,實際上是一個特點,離開誰都不行,都玩兒不轉了。

          Node.js很像摳門的餐廳老板,只聘請1個服務員,服務很多人。結果,比很多服務員效率還高。

          Node.js中所有的I/O都是異步的,回調函數,套回調函數。

          Node.js 適合開發什么?


          Node.js適合用來開發什么樣的應用程序呢?

          善于I/O,不善于計算。因為Node.js最擅長的就是任務調度,如果你的業務有很多的CPU計算,實際上也相當于這個計算阻塞了這個單線程,就不適合Node開發。

          當應用程序需要處理大量并發的I/O,而在向客戶端發出響應之前,應用程序內部并不需要進行非常復雜的處理的時候,Node.js非常適合。Node.js也非常適合與web socket配合,開發長連接的實時交互應用程序。

          比如:

          ● 用戶表單收集

          ● 考試系統

          ● 聊天室

          ● 圖文直播

          ● 提供JSON的API(為前臺Angular使用)

          Node.js 與 PHP、JSP的不同


          Node.js不是一種獨立的語言,與PHP、JSP、Python、Perl、Ruby的“既是語言,也是平臺”不同,Node.js的使用JavaScript進行編程,運行在JavaScript引擎上(V8)。

          與PHP、JSP等相比(PHP、JSP、.net都需要運行在服務器程序上,Apache、Naginx、Tomcat、IIS),Node.js跳過了Apache、Naginx、IIS等HTTP服務器,它自己不用建設在任何服務器軟件之上。Node.js的許多設計理念與經典架構(LAMP=Linux + Apache + MySQL + PHP)有著很大的不同,可以提供強大的伸縮能力。Node.js沒有web容器。

          示例一:頁面顯示"Hello World!"

          JS代碼:

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          //創建服務器,參數就是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           //req表示請求, request;res表示響應,response
           //設置HTTP頭部,狀態碼是200, 文件類型是html。字符編碼格式是 UTF-8
           res.writeHead(200, {'Content-Type':'text/html; charset=UTF-8; '});
           res.end('Hello World!');
          });
          //運行服務器,監聽8083端口
          server.listen(8083, '127.0.0.1');
          

          打開瀏覽器,輸入 127.0.0.1:8083

          示例二:Node.js沒有Web容器

          在使用Apache服務器時,我們經常可以看到在 htdocs目錄中有各種子文件夾,我們要訪問指定頁面,只需要在瀏覽器地址欄中輸入 127.0.0.1:80/app/index.html 類似這樣的結構

          但是,Node.js 由于沒有Web容器,所以在url 地址后面在輸入 /xx.xx 時并不能正常顯示

          有這么一個文件目錄結構:

          fang.html 里面是一個 紅色的、正方形的div,yuan.html 里面是一個 綠色的、圓形的div

          現在新建一個 noWebContainer.js,看能否在url中輸入 fang.html 打開頁面

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          var fs=require('fs');
          //創建服務器,參數是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           
           res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
           res.end("Hello World!");
           
          });
          //運行服務器,監聽4000端口(端口號可以任改)
          server.listen(4000,"127.0.0.1");
          

          運行 127.0.0.1:4000,并在url后面加上 /fang.html,發現完全沒用

          現在初步對“Node.js沒有web容器”這句話有了一點印象了,那想要打開fang.html,怎么辦呢?

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          var fs=require('fs');
          //創建服務器,參數是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           if(req.url=='/fang'){
           fs.readFile('./fang.html', function(err,data){
           //req表示請求,request; res表示響應,response
           //設置HTTP頭部,狀態碼是200,文件類型是html,字符集是utf8
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else{
           res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
           res.end("Hello World!");
           }
          });
          //運行服務器,監聽4000端口(端口號可以任改)
          server.listen(4000,"127.0.0.1");
          

          也就是說,如果 請求的url 里面包含了 /fang,就讀取當前目錄下(./ ---> 表示當前目錄)的 fang.html,否則,就只顯示 Hello World

          同理,我也可以 輸入 /yuan,顯示 yuan.html

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          var fs=require('fs');
          //創建服務器,參數是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           if(req.url=='/fang'){
           fs.readFile('./fang.html', function(err,data){
           //req表示請求,request; res表示響應,response
           //設置HTTP頭部,狀態碼是200,文件類型是html,字符集是utf8
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else if(req.url=='/yuan'){
           fs.readFile('./yuan.html', function(err,data){
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else{
           res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
           res.end("Hello World!");
           }
          });
          //運行服務器,監聽4000端口(端口號可以任改)
          server.listen(4000,"127.0.0.1");
          

          進一步,在 fang.html 中添加一個圖片,從上面的目錄結構中可以看到,圖片的路徑是完全正確的

          <img src="yule.png" alt="圖片">
          

          運行 127.0.0.1:4000/fang,卻發現圖片破了,說明路徑不對。但事實上,我們可以看到,這個路徑是一點問題都沒有的呀,那怎么辦呢?

          又回到了那句話,“Node.js沒有web容器”,所以,還是要用前面的方法處理一下圖片

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          var fs=require('fs');
          //創建服務器,參數是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           if(req.url=='/fang'){
           fs.readFile('./fang.html', function(err,data){
           //req表示請求,request; res表示響應,response
           //設置HTTP頭部,狀態碼是200,文件類型是html,字符集是utf8
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else if(req.url=='/yuan'){
           fs.readFile('./yuan.html', function(err,data){
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else if(req.url=='/yule.png'){
           fs.readFile('./yule.png', function(err,data){
           res.writeHead(200, {"Content-type":"image/jpg"});
           res.end(data);
           })
           }else{
           res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
           res.end("Hello World!");
           }
          });
          //運行服務器,監聽4000端口(端口號可以任改)
          server.listen(4000,"127.0.0.1");
          

          再次運行,圖片可正常顯示

          現在新建一個 yellow.css 樣式表,讓 yuan.html 引入這個css 文件

          yellow.css

          body{background:yellow;}
          

          但是,頁面的背景顏色沒有發生任何改變

          看來 “Node.js沒有web容器”這句話是無處不在呀,同樣需要對 css 文件做處理

          //require表示引包,引包就是引用自己的一個特殊功能
          var http=require('http');
          var fs=require('fs');
          //創建服務器,參數是一個回調函數,表示如果有請求進來,要做什么
          var server=http.createServer(function(req, res){
           if(req.url=='/fang'){
           fs.readFile('./fang.html', function(err,data){
           //req表示請求,request; res表示響應,response
           //設置HTTP頭部,狀態碼是200,文件類型是html,字符集是utf8
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else if(req.url=='/yuan'){
           fs.readFile('./yuan.html', function(err,data){
           res.writeHead(200, {'Content-type':'text/html;charset=UTF-8'});
           res.end(data);
           })
           }else if(req.url=='/yule.png'){
           fs.readFile('./yule.png', function(err,data){
           res.writeHead(200, {"Content-type":"image/jpg"});
           res.end(data);
           })
           }else if(req.url=='/yellow'){
           fs.readFile('./yellow.css', function(err,data){
           res.writeHead(200, {"Content-type":"text/css"});
           res.end(data);
           })
           }else{
           res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
           res.end("Hello World!");
           }
          });
          //運行服務器,監聽4000端口(端口號可以任改)
          server.listen(4000,"127.0.0.1");
          

          再次運行代碼,發現頁面背景顏色變成了黃色


          主站蜘蛛池模板: 亚洲AV无一区二区三区久久| 国产伦精品一区三区视频| 麻豆国产一区二区在线观看 | 久久中文字幕一区二区| 麻豆国产一区二区在线观看| 中文字幕一区二区免费| 中日韩精品无码一区二区三区| 香蕉一区二区三区观| 日韩免费一区二区三区在线| 国产品无码一区二区三区在线蜜桃 | 精品福利一区二区三| 国产在线精品一区在线观看| 国产精品揄拍一区二区| 中文字幕精品无码一区二区三区 | 无码少妇一区二区浪潮免费| 国产视频一区二区在线播放| 国产91精品一区| 欧美av色香蕉一区二区蜜桃小说 | 中文字幕亚洲一区二区三区| 精品免费国产一区二区三区| 五月婷婷一区二区| 人妻无码第一区二区三区| 国产一区三区三区| 亚洲美女高清一区二区三区| 国产一区二区三区不卡在线看| 无码中文字幕人妻在线一区二区三区| 久久久精品人妻一区亚美研究所 | 性色AV一区二区三区无码| 国产福利一区二区三区在线视频| 国产精品女同一区二区| 国精品无码一区二区三区左线| 国产精品免费大片一区二区| 色多多免费视频观看区一区| 国产成人一区二区三区高清| 国产精品资源一区二区| 国产精品一区不卡| 日韩电影在线观看第一区| 男人的天堂亚洲一区二区三区| 国产精品亚洲一区二区无码 | 无码国产精品一区二区免费3p| 久久精品国产一区二区|