最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript表單輸入不能為空驗(yàn)證的完整實(shí)現(xiàn)方案

 更新時間:2025年12月11日 09:19:49   作者:豐雅  
在前端開發(fā)中,使用JavaScript驗(yàn)證用戶輸入是確保表單數(shù)據(jù)完整性的關(guān)鍵步驟,本文詳細(xì)介紹了如何通過JavaScript實(shí)現(xiàn)輸入不能為空的校驗(yàn)邏輯,涵蓋事件監(jiān)聽、DOM操作與表單控制,需要的朋友可以參考下

簡介:

在前端開發(fā)中,使用JavaScript驗(yàn)證用戶輸入是確保表單數(shù)據(jù)完整性的關(guān)鍵步驟。本文詳細(xì)介紹了如何通過JavaScript實(shí)現(xiàn)“輸入不能為空”的校驗(yàn)邏輯,涵蓋事件監(jiān)聽、DOM操作與表單控制。通過 onsubmit 事件或 addEventListener 方式綁定驗(yàn)證函數(shù),利用 trim() 去除空格判斷空值,并結(jié)合 alert 提示和 preventDefault() 阻止無效提交。同時提供通用驗(yàn)證函數(shù)設(shè)計,支持多字段批量校驗(yàn),提升代碼復(fù)用性與可維護(hù)性。該方案可有效攔截空提交,優(yōu)化用戶體驗(yàn)并減輕服務(wù)器壓力。

JavaScript表單驗(yàn)證的深度實(shí)踐:從基礎(chǔ)邏輯到生產(chǎn)級架構(gòu)

在智能家居設(shè)備日益復(fù)雜的今天,確保用戶輸入的有效性已成為前端開發(fā)不可忽視的核心環(huán)節(jié)。想象一下這樣的場景:一位用戶正急著注冊賬號,卻因郵箱格式錯誤反復(fù)提交失敗——如果頁面不能即時反饋問題,而是跳轉(zhuǎn)到一個冷冰冰的“服務(wù)器錯誤”提示頁,這種體驗(yàn)無疑是災(zāi)難性的。而這一切的背后,正是JavaScript表單驗(yàn)證在默默發(fā)揮作用。

我們今天要聊的,不只是“怎么讓輸入框不為空”這么簡單的事。你會發(fā)現(xiàn),看似平平無奇的 trim() preventDefault() ,其實(shí)串聯(lián)起了一整套關(guān)于用戶體驗(yàn)、安全邊界與工程可維護(hù)性的深層設(shè)計哲學(xué)。別眨眼,咱們這就從最基礎(chǔ)的DOM操作開始,一路走到支持異步校驗(yàn)的模塊化驗(yàn)證系統(tǒng)。

當(dāng)你第一次寫JavaScript時,可能就遇到過類似的需求:“用戶名不能為空”。于是你寫了這樣一個函數(shù):

function validateOnSubmit() {
    const input = document.getElementById('username');
    if (input.value.trim() === '') {
        alert('用戶名不能為空');
        return false;
    }
    return true;
}

然后在HTML里這樣綁定:

<form onsubmit="return validateOnSubmit()">

這確實(shí)能工作,但你知道為什么 return false 就能阻止表單提交嗎?

其實(shí), onsubmit 是一個特殊的事件處理器,它會檢查回調(diào)函數(shù)的返回值。 只要返回 false ,瀏覽器就會取消默認(rèn)行為——也就是阻止表單提交 。這是早期Web開發(fā)中最直接的控制方式,但它的問題也很明顯:把邏輯和結(jié)構(gòu)混在一起了。就像你在墻上貼便簽條記事,短期方便,長期來看只會越來越亂。

更優(yōu)雅的做法是使用現(xiàn)代事件模型。比如用 addEventListener 把邏輯抽離出來:

document.getElementById('userForm').addEventListener('submit', function(e) {
    const username = this.username.value.trim();
    if (username === '') {
        alert('用戶名不能為空!');
        e.preventDefault(); // 阻止默認(rèn)提交
    }
});

看到?jīng)]?這里不再依賴函數(shù)返回值,而是通過調(diào)用 e.preventDefault() 顯式地告訴瀏覽器:“先別跳轉(zhuǎn)!”這種方式不僅解耦了JS與HTML,還為后續(xù)擴(kuò)展打下了基礎(chǔ)——比如你想加個加載動畫、記錄埋點(diǎn)數(shù)據(jù),都可以再注冊一個監(jiān)聽器,互不影響。

小知識: 在內(nèi)聯(lián)事件中相當(dāng)于同時執(zhí)行了 e.preventDefault() e.stopPropagation() ,但在 addEventListener 中完全無效!所以別再濫用它了。

那么問題來了:我們到底該怎么判斷“空”?

很多人第一反應(yīng)是:

if (input.value === '') { /* 為空 */ }

但現(xiàn)實(shí)往往更復(fù)雜。用戶可能會復(fù)制粘貼一段內(nèi)容進(jìn)來,前后帶著看不見的空格;或者干脆只敲了幾下空格鍵。這時候 .value 雖然不是空字符串,但語義上依然是“沒填”。

解決方案顯而易見——用 .trim() 去掉首尾空白:

if (input.value.trim() === '') { /* 真正為空 */ }

這個小小的 .trim() 實(shí)際上解決了一個大問題: 區(qū)分“視覺上的空”和“邏輯上的空” 。不過你還得小心一點(diǎn),如果元素根本不存在呢?比如ID寫錯了, getElementById 返回 null ,這時候訪問 .value 就會拋出異常。

所以完整的做法應(yīng)該是:

const input = document.getElementById('username');
if (!input) {
    console.error('找不到指定輸入框');
    return false;
}

const value = input.value;
if (value.trim() === '') {
    alert('請輸入用戶名');
    return false;
}

是不是感覺代碼一下子變啰嗦了?但這正是健壯系統(tǒng)的起點(diǎn):每一步都考慮失敗的可能性。

當(dāng)然,如果你面對的是一個多字段表單(比如注冊頁有姓名、郵箱、電話等),一個個 getElementById 顯然太低效。這時候就可以祭出 querySelectorAll

// 獲取所有帶 required 屬性的輸入框
const requiredFields = document.querySelectorAll('input[required], textarea[required]');

它返回一個 NodeList,你可以用 forEach 遍歷處理:

let isValid = true;

requiredFields.forEach(field => {
    if (field.value.trim() === '') {
        console.warn(`${field.name || field.placeholder} 不能為空`);
        isValid = false;
    }
});

看,幾行代碼就把批量驗(yàn)證搞定了。而且因?yàn)橛昧? [required] 這個屬性,你甚至不需要改JS代碼,只要在HTML里給某個字段加上或去掉 required ,驗(yàn)證邏輯自動適配。這就是“聲明式編程”的魅力所在!

順便提一句,HTML5 的 required 屬性本身就能觸發(fā)瀏覽器原生驗(yàn)證提示,連JS都不需要:

<input type="text" id="username" required placeholder="請輸入用戶名">

當(dāng)用戶試圖提交空值時,瀏覽器會自動彈出提示,并將焦點(diǎn)定位到該字段。這對于無障礙訪問特別友好,屏幕閱讀器也能正確識別必填項。

但它的缺點(diǎn)也很明顯:樣式無法定制,提示語言取決于操作系統(tǒng)設(shè)置,而且一旦禁用JS,你就失去了所有自定義控制能力。所以在實(shí)際項目中,通常是兩者結(jié)合使用——用 required 作為兜底保障,用JS實(shí)現(xiàn)精細(xì)化交互體驗(yàn)。

現(xiàn)在讓我們深入一點(diǎn):什么是真正的“空”?

JavaScript里的“空”可不止一種形態(tài)。 null 、 undefined 、空字符串 '' 、全是空格的字符串 ' ' ,甚至 NaN 0 在某些上下文中也可能被視作“空”。但它們的意義完全不同。

舉個例子,假設(shè)你在做一個問卷系統(tǒng),允許用戶填寫年齡。如果用戶輸入 0 ,你是應(yīng)該報錯說“不能為空”,還是接受這個合法數(shù)值?

顯然,后者才合理。但如果用簡單的 !value 判斷:

if (!value.trim()) { /* 視為空 */ }

0 也會被誤判,因?yàn)樗鼘儆?falsy 值之一。JavaScript中的 falsy 值包括:

  • false
  • 0
  • '' (空字符串)
  • null
  • undefined
  • NaN

所以對于文本輸入,建議始終使用長度判斷:

if (value.trim().length === 0) { /* 真正為空 */ }

而對于數(shù)字類字段,則應(yīng)單獨(dú)處理類型:

function isValidAge(ageStr) {
    const num = Number(ageStr);
    return !isNaN(num) && num >= 0 && num <= 120;
}

為了統(tǒng)一管理這些邏輯,聰明的開發(fā)者通常會封裝一個通用的 isEmpty 工具函數(shù):

function isEmpty(value) {
    if (value == null) return true; // null 或 undefined

    if (typeof value === 'string') {
        return value.trim().length === 0;
    }

    if (Array.isArray(value)) {
        return value.length === 0;
    }

    if (typeof value === 'object') {
        return Object.keys(value).length === 0;
    }

    return false; // 其他類型如 number, boolean 不視為空
}

這個函數(shù)雖然短,但覆蓋了大多數(shù)常見場景。你可以把它放進(jìn)工具庫, anywhere needed

flowchart LR
    Start[開始判斷] --> NullCheck{value == null?}
    NullCheck -- 是 --> ReturnTrue[返回 true]
    NullCheck -- 否 --> TypeCheck{類型判斷}
    TypeCheck --> StringCase[字符串? → trim().length === 0]
    TypeCheck --> ArrayCase[數(shù)組? → length === 0]
    TypeCheck --> ObjectCase[對象? → keys.length === 0]
    TypeCheck --> OtherCase[其他 → false]
    StringCase --> End
    ArrayCase --> End
    ObjectCase --> End
    OtherCase --> End
    End --> ReturnValue[返回結(jié)果]

有了這個基礎(chǔ),接下來構(gòu)建表單驗(yàn)證主函數(shù)就水到渠成了:

function validateForm(form) {
    let isValid = true;

    // 查找所有必填字段
    const requiredInputs = form.querySelectorAll('[required]');

    requiredInputs.forEach(input => {
        if (isEmpty(input.value)) {
            markAsError(input, '此項為必填');
            if (isValid) input.focus(); // 第一個錯誤字段獲取焦點(diǎn)
            isValid = false;
        } else {
            clearError(input);
        }
    });

    return isValid;
}

這里的 markAsError clearError 可以是你自己定義的UI更新函數(shù),比如添加紅色邊框、顯示錯誤圖標(biāo)等。關(guān)鍵是—— 驗(yàn)證邏輯與界面反饋分離 ,這樣未來換皮膚、做國際化都不會影響核心邏輯。

說到事件綁定,不得不提一個常見的誤區(qū):很多人以為 addEventListener 只是用來替代 onsubmit 的語法糖。其實(shí)不然,它的真正價值在于 支持多個監(jiān)聽器共存 。

想象一下,你的表單不僅要驗(yàn)證數(shù)據(jù),還要上報分析日志、防止重復(fù)提交、同步保存草稿……這些功能完全可以各自注冊獨(dú)立的監(jiān)聽器,互不干擾:

form.addEventListener('submit', validateData);     // 驗(yàn)證邏輯
form.addEventListener('submit', trackAnalytics);   // 數(shù)據(jù)埋點(diǎn)
form.addEventListener('submit', disableSubmitBtn); // 防重復(fù)提交
form.addEventListener('submit', saveToLocal);      // 自動保存

每個函數(shù)職責(zé)單一,測試起來也更容易。更重要的是,即使其中一個出錯,也不會阻斷其他邏輯執(zhí)行(除非拋出未捕獲異常)。

再來看看 preventDefault() stopPropagation() 的區(qū)別,這是新手最容易混淆的地方:

方法作用
preventDefault() 阻止元素默認(rèn)行為(如跳轉(zhuǎn)、提交)
stopPropagation() 阻止事件向上冒泡到父級

舉例說明:

<div onclick="console.log('div clicked')">
    <form id="myForm">...</form>
</div>

如果你在表單提交事件中只調(diào)用 e.preventDefault() ,那么頁面不會刷新,但仍然會輸出 div clicked ——因?yàn)槭录^續(xù)冒泡到了外層 <div> 。

而如果你加上 e.stopPropagation() ,就不會觸發(fā)外層點(diǎn)擊事件了。

flowchart LR
    A[用戶點(diǎn)擊submit按鈕] --> B[觸發(fā)submit事件]
    B --> C{是否有preventDefault?}
    C -->|是| D[阻止頁面跳轉(zhuǎn)]
    C -->|否| E[執(zhí)行默認(rèn)提交]
    B --> F{是否有stopPropagation?}
    F -->|是| G[停止向祖先傳遞]
    F -->|否| H[事件繼續(xù)冒泡]

這兩個方法經(jīng)常配合使用,但一定要清楚它們各自的職責(zé)。別為了省事一股腦全加上,否則可能會破壞其他組件的正常行為。

前面說的都是同步驗(yàn)證,但在真實(shí)業(yè)務(wù)中,很多校驗(yàn)必須依賴服務(wù)器響應(yīng)。比如注冊時檢查用戶名是否已被占用,這就沒法靠本地規(guī)則搞定。

這時候就得引入異步驗(yàn)證。但有個致命陷阱: 你不能在 async 函數(shù)中依賴 await 來阻止表單提交 。

看這段代碼有什么問題:

form.addEventListener('submit', async function(e) {
    const response = await fetch('/check-username', { 
        method: 'POST', 
        body: JSON.stringify({ username: this.username.value })
    });
    const data = await response.json();

    if (!data.available) {
        e.preventDefault(); // ? 太晚了!
        alert('用戶名已存在');
    }
});

問題出在哪?當(dāng) JS 執(zhí)行到 await fetch(...) 時,當(dāng)前函數(shù)暫停,但事件循環(huán)不會停下來等它。瀏覽器很可能在等待網(wǎng)絡(luò)響應(yīng)的過程中就已經(jīng)完成了表單提交,頁面早就跳走了。

正確的做法是: 提前阻止默認(rèn)行為,等驗(yàn)證完成后再決定是否手動提交 。

form.addEventListener('submit', async function(e) {
    e.preventDefault(); // ?? 必須一開始就阻止!

    try {
        const response = await fetch('/api/validate', {
            method: 'POST',
            body: new FormData(this)
        });

        const result = await response.json();

        if (result.valid) {
            this.submit(); // 繞過事件監(jiān)聽器直接提交
        } else {
            showError(result.message);
        }
    } catch (err) {
        showError('網(wǎng)絡(luò)異常,請稍后重試');
    }
});

注意這里的 this.submit() 是關(guān)鍵。它不會再次觸發(fā) submit 事件,避免無限循環(huán)。同時還能保持原有的 action method 行為,完美兼容后端接口。

為了讓用戶體驗(yàn)更好,還可以加上加載狀態(tài):

function setLoading(form, loading) {
    const btn = form.querySelector('button[type="submit"]');
    btn.disabled = loading;
    btn.textContent = loading ? '驗(yàn)證中...' : '提交';
}

這樣用戶就知道系統(tǒng)正在工作,而不是卡住了。

隨著項目規(guī)模擴(kuò)大,重復(fù)編寫驗(yàn)證邏輯會變得難以維護(hù)。聰明的做法是把驗(yàn)證規(guī)則抽象成可配置的模塊。

先定義一些基本校驗(yàn)函數(shù):

// validators.js
export const isEmpty = str => typeof str === 'string' ? str.trim().length === 0 : false;
export const isEmail = str => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
export const minLength = (str, len) => str.trim().length >= len;
export const maxLength = (str, len) => str.trim().length <= len;

然后創(chuàng)建一個通用驗(yàn)證器:

function validateInputs(configList) {
    let firstErrorField = null;
    let isValid = true;

    configList.forEach(config => {
        const { element, rules, message } = config;
        const value = element.value;

        for (const rule of rules) {
            if (!rule(value)) {
                showError(element, message);
                if (isValid) {
                    firstErrorField = element;
                }
                isValid = false;
                break;
            }
        }

        if (isValid) {
            clearError(element);
        }
    });

    if (firstErrorField) {
        firstErrorField.focus();
    }

    return isValid;
}

調(diào)用時就像寫配置文件一樣清晰:

form.addEventListener('submit', function(e) {
    const rules = [
        {
            element: this.username,
            rules: [v => !isEmpty(v), v => minLength(v, 3)],
            message: '用戶名至少3個字符'
        },
        {
            element: this.email,
            rules: [v => !isEmpty(v), v => isEmail(v)],
            message: '請輸入有效郵箱'
        }
    ];

    if (!validateInputs(rules)) {
        e.preventDefault();
    }
});

這種模式已經(jīng)非常接近現(xiàn)代表單庫的設(shè)計思想了。你可以進(jìn)一步封裝成類,支持動態(tài)添加/移除規(guī)則、支持自定義錯誤模板、甚至集成i18n多語言提示。

最后,我們必須回到那個永恒的話題:前端驗(yàn)證真的安全嗎?

答案很明確: 不安全 。

無論你的JS寫得多嚴(yán)密,攻擊者都可以輕松繞過:

  • 禁用JavaScript
  • 修改HTML代碼
  • 使用Postman/cURL直接發(fā)請求
  • 注入惡意腳本篡改驗(yàn)證函數(shù)

所以記住這條鐵律: 所有關(guān)鍵校驗(yàn)必須在服務(wù)端重復(fù)執(zhí)行 。

前端驗(yàn)證的作用只有一個:提升用戶體驗(yàn)。讓用戶在提交前就知道哪里錯了,減少無效請求對服務(wù)器的壓力。

而后端才是最終的守門人。它需要做:

  • 重新檢查所有必填字段
  • 過濾XSS、SQL注入等惡意內(nèi)容
  • 驗(yàn)證數(shù)據(jù)類型、長度、格式
  • 執(zhí)行唯一性約束(如用戶名唯一)
  • 記錄操作日志用于審計

這才是真正的縱深防御(Defense in Depth)。前端是禮貌的提醒員,后端才是嚴(yán)格的安檢官。

sequenceDiagram
    participant User
    participant Frontend
    participant Backend

    User->>Frontend: 提交表單
    Frontend->>Frontend: preventDefault()
    Frontend->>Backend: AJAX POST 請求
    alt 響應(yīng)成功
        Backend-->>Frontend: 返回 200 + 成功數(shù)據(jù)
        Frontend->>User: 跳轉(zhuǎn)成功頁
    else 校驗(yàn)失敗
        Backend-->>Frontend: 返回 400 + 錯誤詳情
        Frontend->>User: 高亮錯誤字段
    else 網(wǎng)絡(luò)異常
        Frontend->>User: 提示離線/超時
    end

你看,哪怕前端做了層層校驗(yàn),后端依然要獨(dú)立完成全部驗(yàn)證流程。這不是重復(fù)勞動,而是系統(tǒng)穩(wěn)定性的基石。

總結(jié)一下,一套成熟的表單驗(yàn)證體系應(yīng)該具備以下特征:

? 分層設(shè)計 :HTML5基礎(chǔ)校驗(yàn) + JS增強(qiáng)體驗(yàn) + 服務(wù)端最終把關(guān)
? 關(guān)注點(diǎn)分離 :驗(yàn)證邏輯、UI反饋、事件綁定各司其職
? 可復(fù)用性 :封裝工具函數(shù),支持多表單共享規(guī)則
? 異步友好 :能協(xié)調(diào)遠(yuǎn)程校驗(yàn),防止頁面意外跳轉(zhuǎn)
? 容錯能力強(qiáng) :處理各種邊界情況,不因小失誤導(dǎo)致崩潰

當(dāng)你下次接到“做個注冊頁”的任務(wù)時,不妨想想:我能不能寫出一套既簡單又健壯的驗(yàn)證方案?能不能讓產(chǎn)品同事以后復(fù)制粘貼就能用?

畢竟,最好的代碼,不是最難懂的,而是最容易被人理解和復(fù)用的。

以上就是JavaScript表單輸入不能為空驗(yàn)證的完整實(shí)現(xiàn)方案的詳細(xì)內(nèi)容,更多關(guān)于JavaScript表單輸入不為空驗(yàn)證的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序--特定區(qū)域滾動到頂部時固定的方法

    微信小程序--特定區(qū)域滾動到頂部時固定的方法

    這篇文章主要介紹了微信小程序--特定區(qū)域滾動到頂部時固定的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • js實(shí)現(xiàn)動態(tài)時鐘

    js實(shí)現(xiàn)動態(tài)時鐘

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)動態(tài)時鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 微信小程序基于高德地圖查找位置并顯示文字

    微信小程序基于高德地圖查找位置并顯示文字

    這篇文章主要介紹了微信小程序基于高德地圖查找位置并顯示文字,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Select標(biāo)簽下拉列表二級聯(lián)動級聯(lián)實(shí)例代碼

    Select標(biāo)簽下拉列表二級聯(lián)動級聯(lián)實(shí)例代碼

    這篇文章主要介紹了Select標(biāo)簽下拉列表二級聯(lián)動級聯(lián)實(shí)例代碼,需要的朋友可以參考下
    2014-02-02
  • JavaScript圖像查看庫Viewer.js的使用方法

    JavaScript圖像查看庫Viewer.js的使用方法

    Viewer.js是一款強(qiáng)大的圖片查看器,像門戶網(wǎng)站一般都會有各自的圖片查看器,如果您正需要一款強(qiáng)大的圖片查看器,也許Viewer.js是一個很好的選擇,這篇文章主要介紹了JavaScript圖像查看庫Viewer.js的使用方法,需要的朋友可以參考下
    2025-07-07
  • JavaScript實(shí)現(xiàn)Blob、File、ArrayBuffer、base64、URL之間互轉(zhuǎn)方法

    JavaScript實(shí)現(xiàn)Blob、File、ArrayBuffer、base64、URL之間互轉(zhuǎn)方法

    在JavaScript中處理二進(jìn)制數(shù)據(jù)時,我們常常會遇到需要將Blob對象轉(zhuǎn)換成File對象的情況,這篇文章主要介紹了JavaScript實(shí)現(xiàn)Blob、File、ArrayBuffer、base64、URL之間互轉(zhuǎn)方法的相關(guān)資料,需要的朋友可以參考下
    2026-05-05
  • javascript刪除字符串最后一個字符

    javascript刪除字符串最后一個字符

    需求是一個字符串,想刪除這個字符串最后一個字符,比如“1,2,3,4,5,”,刪除最后一個“,”用javascript怎么實(shí)現(xiàn)?下面給出三種方法
    2014-01-01
  • JS實(shí)現(xiàn)電話號碼的字母組合算法示例

    JS實(shí)現(xiàn)電話號碼的字母組合算法示例

    這篇文章主要介紹了JS實(shí)現(xiàn)電話號碼的字母組合算法,結(jié)合實(shí)例形式分析了javascript組合運(yùn)算的相關(guān)算法原理與操作技巧,需要的朋友可以參考下
    2019-02-02
  • 說明你的Javascript技術(shù)很爛的五個原因

    說明你的Javascript技術(shù)很爛的五個原因

    Javascript在互聯(lián)網(wǎng)上名聲很臭,但你又很難再找到一個像它這樣如此動態(tài)、如此被廣泛使用、如此根植于我們的生活中的另外一種語言。
    2011-04-04
  • 詳解html-webpack-plugin插件(用法總結(jié))

    詳解html-webpack-plugin插件(用法總結(jié))

    這篇文章主要介紹了詳解html-webpack-plugin插件(用法總結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09

最新評論

蒙阴县| 临海市| 衡阳市| 万全县| 内黄县| 延长县| 巩义市| 亳州市| 全南县| 赤峰市| 呈贡县| 洪泽县| 临沭县| 交口县| 沧源| 潍坊市| 北辰区| 虎林市| 瑞安市| 黎城县| 安丘市| 扶风县| 北票市| 辉南县| 德庆县| 伊宁县| 孟津县| 隆昌县| 图片| 永康市| 西畴县| 商城县| 荃湾区| 湟中县| 丰都县| 南开区| 永康市| 晋宁县| 北川| 巴林右旗| 皮山县|