JavaScript基礎:DOM操作詳解

来源:https://www.cnblogs.com/smyhvae/archive/2018/01/27/8366012.html
-Advertisement-
Play Games

本文最初發表於 "博客園" ,併在 "GitHub" 上持續更新 前端的系列文章 。歡迎在GitHub上關註我,一起入門和進階前端。 以下是正文。 前言 JavaScript的組成 JavaScript基礎分為三個部分: ECMAScript:JavaScript的語法標準。包括變數、表達式、運算符 ...


本文最初發表於博客園,併在GitHub上持續更新前端的系列文章。歡迎在GitHub上關註我,一起入門和進階前端。

以下是正文。

前言

JavaScript的組成

JavaScript基礎分為三個部分:

  • ECMAScript:JavaScript的語法標準。包括變數、表達式、運算符、函數、if語句、for語句等。

  • DOM:文檔對象模型,操作網頁上的元素的API。比如讓盒子移動、變色、輪播圖等。

  • BOM:瀏覽器對象模型,操作瀏覽器部分功能的API。比如讓瀏覽器自動滾動。

事件

JS是以事件驅動為核心的一門語言。

事件的三要素

事件的三要素:事件源、事件、事件驅動程式

比如,我用手去按開關,燈亮了。這件事情里,事件源是:手。事件是:按開關。事件驅動程式是:燈的開和關。

再比如,網頁上彈出一個廣告,我點擊右上角的X,廣告就關閉了。這件事情里,事件源是:X。事件是:onclick。事件驅動程式是:廣告關閉了。

於是我們可以總結出:誰引發的後續事件,誰就是事件源。

總結如下:

  • 事件源:引發後續事件的html標簽。

  • 事件:js已經定義好了(見下圖)。

  • 事件驅動程式:對樣式和html的操作。也就是DOM。

代碼書寫步驟如下:(重要)

  • (1)獲取事件源:document.getElementById(“box”); // 類似於Android裡面的findViewById

  • (2)綁定事件: 事件源box.事件onclick = function(){ 事件驅動程式 };

  • (3)書寫事件驅動程式:關於DOM的操作。

最簡單的代碼舉例:(點擊box1,然後彈框)

<body>
<div id="box1"></div>

<script type="text/javascript">
    // 1、獲取事件源
    var div = document.getElementById("box1");
    // 2、綁定事件
    div.onclick = function () {
        // 3、書寫事件驅動程式
        alert("我是彈出的內容");
    }
</script>

</body>

常見的事件如下:

下麵針對這事件的三要素,進行分別介紹。

1、獲取事件源的方式(DOM節點的獲取)

獲取事件源的常見方式如下:

    var div1 = document.getElementById("box1");      //方式一:通過id獲取單個標簽

    var arr1 = document.getElementsByTagName("div1");     //方式二:通過 標簽名 獲得 標簽數組,所以有s

    var arr2 = document.getElementsByClassName("hehe");  //方式三:通過 類名 獲得 標簽數組,所以有s

2、綁定事件的方式

方式一:直接綁定匿名函數

<div id="box1" ></div>

<script type="text/javascript">
    var div1 = document.getElementById("box1");
    //綁定事件的第一種方式
    div1.onclick = function () {
        alert("我是彈出的內容");
    }
</script>

方式二:先單獨定義函數,再綁定

 <div id="box1" ></div>

<script type="text/javascript">
    var div1 = document.getElementById("box1");
    //綁定事件的第二種方式
    div1.onclick = fn;   //註意,這裡是fn,不是fn()。fn()指的是返回值。
    //單獨定義函數
    function fn() {
        alert("我是彈出的內容");
    }
</script>

註意上方代碼的註釋。綁定的時候,是寫fn,不是寫fn()。fn代表的是整個函數,而fn()代表的是返回值。

方式三:行內綁定

<!--行內綁定-->
<div id="box1" onclick="fn()"></div>

<script type="text/javascript">

    function fn() {
        alert("我是彈出的內容");
    }

</script>

註意第一行代碼,綁定時,是寫的"fn()",不是寫的"fn"。因為綁定的這段代碼不是寫在js代碼里的,而是被識別成了字元串

3、事件驅動程式

我們在上面是拿alert舉例,不僅如此,我們還可以操作標簽的屬性和樣式。舉例如下:

點擊滑鼠時,原本粉色的div變大了,背景變紅:

    <style>
        #box1 {
            width: 100px;
            height: 100px;
            background-color: pink;
            cursor: pointer;
        }
    </style>
</head>

<body>

<div id="box1" ></div>

<script type="text/javascript">
    var div1 = document.getElementById("box1");
    //點擊滑鼠時,原本粉色的div變大了,背景變紅了
    div1.onclick = function () {
        div1.style.width = "200px";   //屬性值要寫引號
        div1.style.height = "200px";
        div1.style.backgroundColor = "red";   //屬性名是backgroundColor,不是background-Color
    }
</script>

上方代碼的註意事項:

  • 在js里寫屬性值時,要用引號
  • 在js里寫屬性名時,是backgroundColor,不是CSS裡面的background-Color

實現效果如下:

onload事件

onload事件比較特殊,這裡單獨講一下。

當頁面載入(文本和圖片)完畢的時候,觸發onload事件。

舉例:

<script type="text/javascript">
    window.onload = function () {
        console.log("smyhvae");  //等頁面載入完畢時,列印字元串
    }
</script>

有一點我們要知道:js的載入是和html同步載入的。因此,如果使用元素在定義元素之前,容易報錯。這個時候,onload事件就能派上用場了,我們可以把使用元素的代碼放在onload里,就能保證這段代碼是最後執行。

建議是:整個頁面上所有元素載入完畢在執行js內容。所以,window.onload可以預防使用標簽在定義標簽之前。

事件舉例:京東頂部廣告欄

比如上面這張圖,當滑鼠點擊右上角的X時,關掉整個廣告欄,這就要用到事件。

代碼實現如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .top-banner {
            background-color: pink;
            height: 80px;
        }
        .w {
            width: 1210px;
            margin: 10px auto;
            position: relative;
        }
        img {
            width: 1210px;
            height: 80px;
            background-color: blue;
        }
        a {
            position: absolute;
            top: 5px;
            right: 5px;
            color: #fff;
            background-color: #000;
            text-decoration: none;
            width: 20px;
            height: 20px;
            font: 700 14px/20px "simsum";
            text-align: center;
        }
        .hide {
            display: none!important;
        }
    </style>
</head>
<body>
    <div class="top-banner" id="topBanner">
        <div class="w">
            <img src="" alt=""/>
            <a href="#" id="closeBanner">×</a>
        </div>
    </div>


<script>
    //需求:點擊案例,隱藏盒子。
    //思路:點擊a鏈接,讓top-banner這個盒子隱藏起來(加隱藏類名)。

    //1.獲取事件源和相關元素
    var closeBanner = document.getElementById("closeBanner");
    var topBanner = document.getElementById("topBanner");
    //2.綁定事件
    closeBanner.onclick = function () {
        //3.書寫事件驅動程式
        //類控制
//        topBanner.className += " hide"; //保留原類名,添加新類名
        topBanner.className = "hide";//替換舊類名
//        topBanner.style.display = "none";
    }

</script>
</body>
</html>

註意最後一行代碼,這種方式會替換舊類名,意思是,不管之前的類名叫什麼,都會被修改。

事件舉例:

要求實現效果:當滑鼠懸停在img上時,更換為另外一張圖片;滑鼠離開時,還原為本來的圖片。

代碼實現:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script>
        //window.onload頁面載入完畢以後再執行此代碼
        window.onload = function () {
            //需求:滑鼠放到img上,更換為另一張圖片,也就是修改路徑(src的值)。
            //步驟:
            //1.獲取事件源
            //2.綁定事件
            //3.書寫事件驅動程式

            //1.獲取事件源
            var img = document.getElementById("box");
            //2.綁定事件(懸停事件:滑鼠進入到事件源中立即出發事件)
            img.onmouseover = function () {
                //3.書寫事件驅動程式(修改src)
                img.src = "image/jd2.png";
//                this.src = "image/jd2.png";
            }

            //1.獲取事件源
            var img = document.getElementById("box");
            //2.綁定事件(懸停事件:滑鼠進入到事件源中立即出發事件)
            img.onmouseout = function () {
                //3.書寫事件驅動程式(修改src)
                img.src = "image/jd1.png";
            }
        }
    </script>
</head>
<body>

    <img id="box" src="image/jd1.png" style="cursor: pointer;border: 1px solid #ccc;"/>

</body>
</html>

DOM的介紹

什麼是DOM

DOM:文檔對象模型。DOM 為文檔提供了結構化表示,並定義瞭如何通過腳本來訪問文檔結構。目的其實就是為了能讓js操作html元素而制定的一個規範。

DOM就是由節點組成的。

解析過程

HTML載入完畢,渲染引擎會在記憶體中把HTML文檔,生成一個DOM樹,getElementById是獲取內中DOM上的元素節點。然後操作的時候修改的是該元素的屬性

DOM樹(一切都是節點)

DOM的數據結構如下:

上圖可知,在HTML當中,一切都是節點:(非常重要)

  • 元素節點:HMTL標簽。

  • 文本節點:標簽中的文字(比如標簽之間的空格、換行)

  • 屬性節點::標簽的屬性。

整個html文檔就是一個文檔節點。所有的節點都是Object。

DOM可以做什麼

  • 找對象(元素節點)

  • 設置元素的屬性值

  • 設置元素的樣式

  • 動態創建和刪除元素

  • 事件的觸發響應:事件源、事件、事件的驅動程式

DOM節點的獲取

DOM節點的獲取方式其實就是獲取事件源的方式,在上一段已經講到。這裡再重覆一下。

操作元素節點,必須首先找到該節點。有三種方式可以獲取DOM節點:

    var div1 = document.getElementById("box1");      //方式一:通過id獲取單個標簽

    var arr1 = document.getElementsByTagName("div1");     //方式二:通過 標簽名 獲得 標簽數組,所以有s

    var arr2 = document.getElementsByClassName("hehe");  //方式三:通過 類名 獲得 標簽數組,所以有s

既然方式二、方式三獲取的是標簽數組,那麼習慣性是先遍歷之後再使用

特殊情況:數組中的值只有1個。即便如此,這一個值也是包在數組裡的。這個值的獲取方式如下:

    document.getElementsByTagName("div1")[0];    //取數組中的第一個元素

    document.getElementsByClassName("hehe")[0];  //取數組中的第一個元素

DOM訪問關係的獲取

DOM的節點並不是孤立的,因此可以通過DOM節點之間的相對關係對它們進行訪問。如下:

節點的訪問關係,是以屬性的方式存在的。

JS中的父子兄訪問關係:

這裡我們要重點知道parentNodechildren這兩個屬性的用法。下麵分別介紹。

獲取父節點

調用者就是節點。一個節點只有一個父節點,調用方式就是

    節點.parentNode

獲取兄弟節點

1、下一個節點 | 下一個元素節點

Sibling的中文是兄弟

(1)nextSibling:

  • 火狐、谷歌、IE9+版本:都指的是下一個節點(包括標簽、空文檔和換行節點)。

  • IE678版本:指下一個元素節點(標簽)。

(2)nextElementSibling:

  • 火狐、谷歌、IE9+版本:都指的是下一個元素節點(標簽)。

總結:為了獲取下一個元素節點,我們可以這樣做:在IE678中用nextSibling,在火狐谷歌IE9+以後用nextElementSibling,於是,綜合這兩個屬性,可以這樣寫:

    下一個兄弟節點 = 節點.nextElementSibling || 節點.nextSibling

2、前一個節點 | 前一個元素節點

previous的中文是:前一個。

(1)previousSibling:

  • 火狐、谷歌、IE9+版本:都指的是前一個節點(包括標簽、空文檔和換行節點)。

  • IE678版本:指前一個元素節點(標簽)。

(2)previousElementSibling:

  • 火狐、谷歌、IE9+版本:都指的是前一個元素節點(標簽)。

總結:為了獲取前一個元素節點,我們可以這樣做:在IE678中用previousSibling,在火狐谷歌IE9+以後用previousElementSibling,於是,綜合這兩個屬性,可以這樣寫:

    前一個兄弟節點 = 節點.previousElementSibling || 節點.previousSibling

3、補充:獲得任意一個兄弟節點:

    節點自己.parentNode.children[index];  //隨意得到兄弟節點

獲取單個的子節點

1、第一個子節點 | 第一個子元素節點

(1)firstChild:

  • 火狐、谷歌、IE9+版本:都指的是第一個子節點(包括標簽、空文檔和換行節點)。

  • IE678版本:指第一個子元素節點(標簽)。

(2)firstElementChild:

  • 火狐、谷歌、IE9+版本:都指的是第一個子元素節點(標簽)。

總結:為了獲取第一個子元素節點,我們可以這樣做:在IE678中用firstChild,在火狐谷歌IE9+以後用firstElementChild,於是,綜合這兩個屬性,可以這樣寫:

    第一個子元素節點 = 節點.firstElementChild || 節點.firstChild

2、最後一個子節點 | 最後一個子元素節點

(1)lastChild:

  • 火狐、谷歌、IE9+版本:都指的是最後一個子節點(包括標簽、空文檔和換行節點)。

  • IE678版本:指最後一個子元素節點(標簽)。

(2)lastElementChild:

  • 火狐、谷歌、IE9+版本:都指的是最後一個子元素節點(標簽)。

總結:為了獲取最後一個子元素節點,我們可以這樣做:在IE678中用lastChild,在火狐谷歌IE9+以後用lastElementChild,於是,綜合這兩個屬性,可以這樣寫:

    最後一個子元素節點 = 節點.lastElementChild || 節點.lastChild

獲取所有的子節點

(1)childNodes:標準屬性。返回的是指定元素的子節點的集合(包括元素節點、所有屬性、文本節點)。是W3C的親兒子。

  • 火狐 谷歌等高本版會把換行也看做是子節點。

用法:

    子節點數組 = 父節點.childNodes;   //獲取所有節點。

(2)children:非標準屬性。返回的是指定元素的子元素節點的集合。【重要】

  • 它只返回HTML節點,甚至不返迴文本節點。
  • 在IE6/7/8中包含註釋節點(在IE678中,註釋節點不要寫在裡面)。

雖然不是標準的DOM屬性,但它和innerHTML方法一樣,得到了幾乎所有瀏覽器的支持。

用法:(用的最多

    子節點數組 = 父節點.children;   //獲取所有節點。用的最多。

nodeType

這裡講一下nodeType。

  • nodeType == 1 表示的是元素節點(標簽) 。記住:元素就是標簽。

  • nodeType == 2 表示是屬性節點 瞭解

  • nodeType == 3 是文本節點 瞭解

DOM節點操作(重要)

上一段的內容:節點的訪問關係都是屬性

本段的內容:節點的操作都是函數(方法)。

創建節點

格式如下:

    新的標簽(元素節點) = document.createElement("標簽名");

比如,如果我們想創建一個li標簽,或者是創建一個不存在的adbc標簽,可以這樣做:

<script type="text/javascript">
    var a1 = document.createElement("li");   //創建一個li標簽
    var a2 = document.createElement("adbc");   //創建一個不存在的標簽

    console.log(a1);
    console.log(a2);

    console.log(typeof a1);
    console.log(typeof a2);
</script>

列印結果:

插入節點

插入節點有兩種方式,它們的含義是不同的。

方式1:

    父節點.appendChild(新的子節點);

解釋:父節點的最後插入一個新的子節點。

方式2:

    父節點.insertBefore(新的子節點,作為參考的子節點)

解釋:

  • 在參考節點前插入一個新的節點。
  • 如果參考節點為null,那麼他將在父節點最後插入一個子節點。

我們可以看到,li標簽確實被插入到了box1標簽的裡面,和box2併列了。

方式2的舉例:

我們可以看到,b1標簽被插入到了box1標簽的裡面,和a1標簽併列,在a1標簽的前面。

刪除節點

格式如下:

    父節點.removeChild(子節點);

解釋:用父節點刪除子節點。必須要指定是刪除哪個子節點。

如果我想刪除自己這個節點,可以這麼做:

    node1.parentNode.removeChild(node1);

複製節點(克隆節點)

格式如下:

    要複製的節點.cloneNode();       //括弧里不帶參數和帶參數false,效果是一樣的。

    要複製的節點.cloneNode(true);

括弧裡帶不帶參數,效果是不同的。解釋如下:

  • 不帶參數/帶參數false:只複製節點本身,不複製子節點。

  • 帶參數true:既複製節點本身,也複製其所有的子節點。

設置節點的屬性

我們可以獲取節點的屬性值、設置節點的屬性值、刪除節點的屬性。

我們就統一拿下麵這個標簽來舉例:

    <img src="images/1.jpg" class="image-box" title="美女圖片" alt="地鐵一瞥" id="a1">

下麵分別介紹。

1、獲取節點的屬性值

方式1:

    元素節點.屬性;
    元素節點[屬性];

舉例:(獲取節點的屬性值)

<body>
<img src="images/1.jpg" class="image-box" title="美女圖片" alt="地鐵一瞥" id="a1">

<script type="text/javascript">
    var myNode = document.getElementsByTagName("img")[0];

    console.log(myNode.src);
    console.log(myNode.className);    //註意,是className,不是class
    console.log(myNode.title);

    console.log("------------");

    console.log(myNode["src"]);
    console.log(myNode["className"]); //註意,是className,不是class
    console.log(myNode["title"]);
</script>
</body>

上方代碼中的img標簽,有各種屬性,我們可以逐一獲取,列印結果如下:

方式2:(推薦)

    元素節點.getAttribute("屬性名稱");

舉例:

    console.log(myNode.getAttribute("src"));
    console.log(myNode.getAttribute("class"));   //註意是class,不是className
    console.log(myNode.getAttribute("title"));

列印結果:

方式1和方式2的區別在於:前者是直接操作標簽,後者是把標簽作為DOM節點。推薦方式2。

2、設置節點的屬性值

方式1舉例:(設置節點的屬性值)

    myNode.src = "images/2.jpg"   //修改src的屬性值
    myNode.className = "image2-box";  //修改class的name

方式2:(推薦)

    元素節點.setAttribute(屬性名, 新的屬性值);

方式2舉例:(設置節點的屬性值)

    myNode.setAttribute("src","images/3.jpg");
    myNode.setAttribute("class","image3-box");
    myNode.setAttribute("id","你好");

3、刪除節點的屬性

格式:

    元素節點.removeAttribute(屬性名);

舉例:(刪除節點的屬性)

    myNode.removeAttribute("class");
    myNode.removeAttribute("id");

我的公眾號

想學習代碼之外的軟技能?不妨關註我的微信公眾號:生命團隊(id:vitateam)。

掃一掃,你將發現另一個全新的世界,而這將是一場美麗的意外:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文地址: "一個輕量級的Android資料庫操作工具" 寫了一個輕量級的Android操作資料庫的ORM工具。方便Android定義資料庫,操作資料庫(增刪改查),資料庫更新,實現了Android對象與資料庫對象之間的映射。源碼地址: "輕量級Android操作資料庫ORM工具" 。可以直接gra ...
  • 1.把要導入成Mudle的項目修改成符合Library的格式 修改該項目中bulid.gradle文件中第一行代碼 把 修改為 然後,修改AndroidManifiest.xml文件中配置信息,此處主要是把原來配置的項目Style等配置以及MainActivity配置刪除,這樣處理是為了防止重覆。以 ...
  • Gradle是一個基於Apache Ant和Apache Maven概念的 項目自動化構建工具 。 它使用一種基於Groovy的特定領域語言(DSL)來聲明項目配置,真正起作用的是Plugin,Gradle預設提供了許多常用的Plugin,如構建Java項目的Plugin、War、Ear等。 Gra ...
  • 小程式支持打開移動應用到底是怎麼回事?什麼APP都可以打開麽? ...
  • DreamweaverCS6安裝與破解 一、背景介紹:同學畢業分佈圖項目計劃簡介 哎哎哎,炸麽說呢,對於Web前端設計來說,純手撕html部分代碼實在是難受。 對於想做地圖這類的就“必須”用這個老工具啦: 0、準備把高中畢業同學分佈圖做一下。之前看到的大多數只是一張圖,實在太LOW,太沒實用性,太不 ...
  • 相信你在寫JavaScript代碼的時候也碰到過很頭疼的時刻,比如對象的屬性名或方法名大小寫錯了,或是記不得某個對象有沒有某個屬性,害怕最新的ES標準有的瀏覽器還沒有支持...等等種種問題,那麼你需要使用TypeScript,你會愛上她的(●'◡'●)。 TypeScript是JavaScript的 ...
  • 18 01 28早上6:30的火車,從三亞回老家,票難買啊。好激動~ 聲明:文中涉及到的數據和第三方介面、url僅供學習使用,請勿它用~ 這幾天都在磨著搭建本地測試環境,看到省市區數據表裡面是空的,想著以前的老數據還是13年採集的,含省市區縣4級數據共4.8萬條,時間久了,使用過程中發現有些新的城市 ...
  • $("span").text("添加的內容");添加文本內容方式。 $("span").html("<font color='red'>兩次密碼輸入不一致</font>");添加HTML元素。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...