果要做一個(gè)網(wǎng)站應(yīng)用,不可避免的會(huì)遇到表單的提交及獲取參數(shù)的值,下面我們來(lái)看看用node.js + express怎么做
先來(lái)構(gòu)建一個(gè)表單簡(jiǎn)單模擬登錄GET方式提交數(shù)據(jù)
1.打開subform.ejs文件,修改文件代碼為如下:
<%= title %> <% include nav %> 用戶名: 密碼:
2.打開subform.js我們?cè)囍邮諈?shù)值并輸出到控制臺(tái)
var express = require('express');var router = express.Router();router.get('/', function(req, res) { var userName = req.query.txtUserName, userPwd = req.query.txtUserPwd, userName2 = req.param('txtUserName'), userPwd2 = req.param('txtUserPwd'); console.log('req.query用戶名:'+userName); console.log('req.query密碼:'+userPwd); console.log('req.param用戶名:'+userName2); console.log('req.param密碼:'+userPwd2); res.render('subform', { title: '提交表單及接收參數(shù)示例' });});module.exports = router;subform.js get方式源碼
3.運(yùn)行,并提交表單 在瀏覽器中運(yùn)行:http://localhost:3000/subform,輸入表單項(xiàng)并提交,可以發(fā)現(xiàn)url發(fā)生了變化
我們?cè)倏纯纯刂婆_(tái)的輸出
我們完成了GET方式提交表單并接收到了值,不錯(cuò)_!(稍后在后面再去講得到值的方式和區(qū)別)
再來(lái)在上面的代碼基礎(chǔ)上去修改一下表單的method簡(jiǎn)單模擬登錄POST方式提交數(shù)據(jù)
1.首先修改一下subform.ejs文件中的form標(biāo)簽,修改為如下:
...
2.再在subform.js中添加代碼,接收post提交、接收參數(shù)并輸出到控制臺(tái)
...router.post('/',function(req, res){ var userName = req.body.txtUserName, userPwd = req.body.txtUserPwd, userName2 = req.param('txtUserName'), userPwd2 = req.param('txtUserPwd'); console.log('req.body用戶名:'+userName); console.log('req.body密碼:'+userPwd); console.log('req.param用戶名:'+userName2); console.log('req.param密碼:'+userPwd2); res.render('subform', { title: '提交表單及接收參數(shù)示例' });});...
3.運(yùn)行,并提交表單 在瀏覽器中運(yùn)行:http://localhost:3000/subform,輸入表單項(xiàng)并提交,可以發(fā)現(xiàn)url不會(huì)發(fā)生變化
我們?cè)倏纯纯刂婆_(tái)的輸出
再回過(guò)頭看看GET和POST方式接收值,從直接效果上來(lái)看
req.query:我用來(lái)接收GET方式提交參數(shù)
req.body:我用來(lái)接收POST提交的參數(shù)
req.params:兩種都能接收到 大家自行看看Express的Request部分的API:http://expressjs.com/en/api.html#req.params
這里著重解釋一下req.body,Express處理這個(gè)post請(qǐng)求是通過(guò)中間件bodyParser,你可以看到app.js中有一塊代碼
...var bodyParser = require('body-parser');...app.use(bodyParser.json());app.use(bodyParser.urlencoded());...
沒(méi)有這個(gè)中間件Express就不知道怎么處理這個(gè)請(qǐng)求,通過(guò)bodyParser中間件分析 application/x-www-form-urlencoded和application/json請(qǐng)求,并把變量存入req.body,這種我們才能夠獲取到!
BOM (Browser Object Model),瀏覽器對(duì)象模型,提供了獨(dú)立于內(nèi)容與瀏覽器窗口進(jìn)行交互的對(duì)象
其作用就是跟瀏覽器做一些交互效果,比如如何進(jìn)行頁(yè)面的后退,前進(jìn),刷新,瀏覽器的窗口發(fā)生變化,滾動(dòng)條的滾動(dòng),以及獲取客戶的一些信息如:瀏覽器品牌版本,屏幕分辨率
瀏覽器的全部?jī)?nèi)容可以看成DOM,整個(gè)瀏覽器可以看成BOM。區(qū)別如下:
使用 window 對(duì)象可以訪問(wèn)客戶端其他對(duì)象,這種關(guān)系構(gòu)成瀏覽器對(duì)象模型,window 對(duì)象代表根節(jié)點(diǎn),瀏覽器對(duì)象關(guān)系的關(guān)系如圖所示,每個(gè)對(duì)象說(shuō)明如下。
當(dāng)然我們可以吧window下的所有子對(duì)象看成他的他的屬性,只不過(guò)屬性也是一個(gè)對(duì)象而已。其實(shí)window也有很多常用的方法:
Bom的核心對(duì)象是window,它表示瀏覽器的一個(gè)實(shí)例
在瀏覽器中,window對(duì)象有雙重角色,即是瀏覽器窗口的一個(gè)接口,又是全局對(duì)象
因此所有在全局作用域中聲明的變量、函數(shù)都會(huì)變成window對(duì)象的屬性和方法
var name = 'js每日一題';
function lookName(){
alert(this.name);
}
console.log(window.name); //js每日一題
lookName(); //js每日一題
window.lookName(); //js每日一題
關(guān)于窗口控制方法如下:
window.open() 既可以導(dǎo)航到一個(gè)特定的url,也可以打開一個(gè)新的瀏覽器窗口
如果 window.open() 傳遞了第二個(gè)參數(shù),且該參數(shù)是已有窗口或者框架的名稱,那么就會(huì)在目標(biāo)窗口加載第一個(gè)參數(shù)指定的URL
window.open('htttp://www.vue3js.cn','topFrame')
==> < a href=" " target="topFrame"></ a>
window.open() 會(huì)返回新窗口的引用,也就是新窗口的 window 對(duì)象
const myWin = window.open('http://www.vue3js.cn','myWin')
window.close() 僅用于通過(guò) window.open() 打開的窗口
新創(chuàng)建的 window 對(duì)象有一個(gè) opener 屬性,該屬性指向打開他的原始窗口對(duì)象
Window的子對(duì)象主要有如下幾個(gè):
使用 window 對(duì)象的 open() 方法可以打開一個(gè)新窗口。用法如下:
window.open (URL, name, features, replace)
參數(shù)列表如下:
該方法返回值為新創(chuàng)建的 window 對(duì)象,使用它可以引用新創(chuàng)建的窗口。
新創(chuàng)建的 window 對(duì)象擁有一個(gè) opener 屬性,引用打開它的原始對(duì)象。opener 只在彈出窗口的最外層 window 對(duì)象(top)中定義,而且指向調(diào)用 window.open() 方法的窗口或框架。
下面示例演示了打開的窗口與原窗口之間的關(guān)系。
win = window.open(); //打開新的空白窗口win.document.write ("<h1>這是新打開的窗口</h1>"); //在新窗口中輸出提示信息win.focus (); //讓原窗口獲取焦點(diǎn)win.opener.document.write ("<h1>這是原來(lái)窗口</h1>"); //在原窗口中輸出提示信息console.log(win.opener == window); //檢測(cè)window.opener屬性值
使用 window 的 close() 方法可以關(guān)閉一個(gè)窗口。例如,關(guān)閉一個(gè)新創(chuàng)建的 win 窗口可以使用下面的方法實(shí)現(xiàn)。
win.close;
如果在打開窗口內(nèi)部關(guān)閉自身窗口,則應(yīng)該使用下面的方法。
純文本復(fù)制
window.close;
使用 window.closed 屬性可以檢測(cè)當(dāng)前窗口是否關(guān)閉,如果關(guān)閉則返回 true,否則返回 false。
下面示例演示如何自動(dòng)彈出一個(gè)窗口,然后設(shè)置半秒鐘之后自動(dòng)關(guān)閉該窗口,同時(shí)允許用戶單擊頁(yè)面超鏈接,更換彈出窗口內(nèi)顯示的網(wǎng)頁(yè) URL。
var url = "c.biancheng.net"; //要打開的網(wǎng)頁(yè)地址var features = "height=500, width=800, top=100, left=100, toolbar=no, menubar=no, scrollbars=no,resizable=no, location=no, status=no"; //設(shè)置新窗口的特性//動(dòng)態(tài)生成一個(gè)超鏈接document.write('<a href="c.biancheng.net" target="newW">切換到C語(yǔ)言中文網(wǎng)首頁(yè)</a>');var me = window.open(url, "newW", featrues); //打開新窗口setTimeout (function () { //定時(shí)器 if (me.closed) { console.log("創(chuàng)建的窗口已經(jīng)關(guān)閉。"); } else { me.close(); }}, 5000); //半秒鐘之后關(guān)閉該窗口
url地址如下:
http://foouser:barpassword@www.wrox.com:80/WileyCDA/?q=javascript#contents
location屬性描述如下:
屬性名 | 例子 | 說(shuō)明 |
hash | "#contents" | utl中#后面的字符,沒(méi)有則返回空串 |
host | www.wrox.com:80 | 服務(wù)器名稱和端口號(hào) |
hostname | www.wrox.com | 域名,不帶端口號(hào) |
href | http://www.wrox.com:80/WileyCDA/?q=javascript#contents | 完整url |
pathname | "/WileyCDA/" | 服務(wù)器下面的文件路徑 |
port | 80 | url的端口號(hào),沒(méi)有則為空 |
protocol | http: | 使用的協(xié)議 |
search | ?q=javascript | url的查詢字符串,通常為?后面的內(nèi)容 |
除了 hash之外,只要修改location的一個(gè)屬性,就會(huì)導(dǎo)致頁(yè)面重新加載新URL
location.reload(),此方法可以重新刷新當(dāng)前頁(yè)面。這個(gè)方法會(huì)根據(jù)最有效的方式刷新頁(yè)面,如果頁(yè)面自上一次請(qǐng)求以來(lái)沒(méi)有改變過(guò),頁(yè)面就會(huì)從瀏覽器緩存中重新加載
如果要強(qiáng)制從服務(wù)器中重新加載,傳遞一個(gè)參數(shù)true即可
window.name屬性用于設(shè)置當(dāng)前瀏覽器窗口的名字。它有一個(gè)特點(diǎn),就是瀏覽器刷新后,該屬性保持不變。所以,可以把值存放在該屬性內(nèi),然后跨頁(yè)面、甚至跨域名使用。當(dāng)然,這個(gè)值有可能被其他網(wǎng)站的頁(yè)面改寫。
window.name = "Hello World!";
console.log(window.name);
各個(gè)瀏覽器對(duì)這個(gè)值的儲(chǔ)存容量有所不同,但是一般來(lái)說(shuō),可以高達(dá)幾MB。
該屬性只能保存字符串,且當(dāng)瀏覽器窗口關(guān)閉后,所保存的值就會(huì)消失。因此局限性比較大,但是與iFrame窗口通信時(shí),非常有用。
這兩個(gè)屬性返回網(wǎng)頁(yè)的CSS布局占據(jù)的瀏覽器窗口的高度和寬度,單位為像素。很顯然,當(dāng)用戶放大網(wǎng)頁(yè)的時(shí)候(比如將網(wǎng)頁(yè)從100%的大小放大為200%),這兩個(gè)屬性會(huì)變小。
注意,這兩個(gè)屬性值包括滾動(dòng)條的高度和寬度。
window.pageXOffset屬性返回頁(yè)面的水平滾動(dòng)距離,window.pageYOffset屬性返回頁(yè)面的垂直滾動(dòng)距離。這兩個(gè)屬性的單位為像素。
window.frames返回一個(gè)類似數(shù)組的對(duì)象,成員為頁(yè)面內(nèi)的所有框架,包括frame元素和iframe元素。需要注意的是,window.frames的每個(gè)成員對(duì)應(yīng)的是框架內(nèi)的窗口(即框架的window對(duì)象),獲取每個(gè)框架的DOM樹,需要使用window.frames[0].document。
var iframe = window.getElementsByTagName("iframe")[0];
var iframe_title = iframe.contentWindow.title;
上面代碼用于獲取框架頁(yè)面的標(biāo)題。
iframe元素遵守同源政策,只有當(dāng)父頁(yè)面與框架頁(yè)面來(lái)自同一個(gè)域名,兩者之間才可以用腳本通信,否則只有使用window.postMessage方法。
在iframe框架內(nèi)部,使用window.parent指向父頁(yè)面。
window.self和window.window屬性都指向窗口本身。這兩個(gè)屬性只讀。
window.self === window // true
window.window === window // true
window.frames屬性返回一個(gè)類似數(shù)組的對(duì)象,成員為頁(yè)面內(nèi)所有框架窗口,包括frame元素和iframe元素。window.frames[0]表示頁(yè)面中第一個(gè)框架窗口。
如果iframe元素設(shè)置了id或name屬性,那么就可以用屬性值,引用這個(gè)iframe窗口。比如<iframe name="myIFrame">可以用frames['myIFrame']或者frames.myIFrame來(lái)引用。
frames屬性實(shí)際上是window對(duì)象的別名。
frames === window // true
因此,frames[0]也可以用window[0]表示。但是,從語(yǔ)義上看,frames更清晰,而且考慮到window還是全局對(duì)象,因此推薦表示多窗口時(shí),總是使用frames[0]的寫法。
window.length屬性返回當(dāng)前網(wǎng)頁(yè)包含的框架總數(shù)。如果當(dāng)前網(wǎng)頁(yè)不包含frame和iframe元素,那么window.length就返回0。
window.frames.length === window.length // true
上面代碼表示,window.frames.length與window.length應(yīng)該是相等的。
window.frameElement屬性主要用于當(dāng)前窗口嵌在另一個(gè)網(wǎng)頁(yè)的情況(嵌入<object>、<iframe>或<embed>元素),返回當(dāng)前窗口所在的那個(gè)元素節(jié)點(diǎn)。如果當(dāng)前窗口是頂層窗口,或者所嵌入的那個(gè)網(wǎng)頁(yè)不是同源的,該屬性返回null。
// HTML 代碼如下
// <iframe src="about.html"></iframe>
// 下面的腳本在 about.html 里面
var frameEl = window.frameElement;
if (frameEl) {
frameEl.src = 'other.html';
}
上面代碼中,frameEl變量就是<iframe>元素。
window.top屬性指向最頂層窗口,主要用于在框架窗口(frame)里面獲取頂層窗口。
window.parent屬性指向父窗口。如果當(dāng)前窗口沒(méi)有父窗口,window.parent指向自身。
if (window.parent !== window.top) {
// 表明當(dāng)前窗口嵌入不止一層
}
對(duì)于不包含框架的網(wǎng)頁(yè),這兩個(gè)屬性等同于window對(duì)象。
window.status屬性用于讀寫瀏覽器狀態(tài)欄的文本。但是,現(xiàn)在很多瀏覽器都不允許改寫狀態(tài)欄文本,所以使用這個(gè)方法不一定有效。
window.devicePixelRatio屬性返回一個(gè)數(shù)值,表示一個(gè) CSS 像素的大小與一個(gè)物理像素的大小之間的比率。也就是說(shuō),它表示一個(gè) CSS 像素由多少個(gè)物理像素組成。它可以用于判斷用戶的顯示環(huán)境,如果這個(gè)比率較大,就表示用戶正在使用高清屏幕,因此可以顯示較大像素的圖片。
navigator 對(duì)象主要用來(lái)獲取瀏覽器的屬性,區(qū)分瀏覽器類型。屬性較多,且兼容性比較復(fù)雜
下表列出了navigator對(duì)象接口定義的屬性和方法:
Navigator.userAgent屬性返回瀏覽器的User-Agent字符串,用來(lái)標(biāo)示瀏覽器的種類。下面是Chrome瀏覽器的User-Agent。
navigator.userAgent
// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
通過(guò)userAgent屬性識(shí)別瀏覽器,不是一個(gè)好辦法。因?yàn)楸仨毧紤]所有的情況(不同的瀏覽器,不同的版本),非常麻煩,而且無(wú)法保證未來(lái)的適用性,更何況各種上網(wǎng)設(shè)備層出不窮,難以窮盡。所以,現(xiàn)在一般不再識(shí)別瀏覽器了,而是使用“功能識(shí)別”方法,即逐一測(cè)試當(dāng)前瀏覽器是否支持要用到的JavaScript功能。
不過(guò),通過(guò)userAgent可以大致準(zhǔn)確地識(shí)別手機(jī)瀏覽器,方法就是測(cè)試是否包含“mobi”字符串。
var ua = navigator.userAgent.toLowerCase();
if (/mobi/i.test(ua)) {
// 手機(jī)瀏覽器
} else {
// 非手機(jī)瀏覽器
}
如果想要識(shí)別所有移動(dòng)設(shè)備的瀏覽器,可以測(cè)試更多的特征字符串。
/mobi|android|touch|mini/i.test(ua)
navigator.plugins屬性返回一個(gè)類似數(shù)組的對(duì)象,成員是瀏覽器安裝的插件,比如Flash、ActiveX等。
保存的純粹是客戶端能力信息,也就是瀏覽器窗口外面的客戶端顯示器的信息,比如像素寬度和像素高度
一般使用以上兩個(gè)屬性,了解設(shè)備的分辨率。上面代碼顯示,某設(shè)備的分辨率是1920x1080。
除非調(diào)整顯示器的分辨率,否則這兩個(gè)值可以看作常量,不會(huì)發(fā)生變化。顯示器的分辨率與瀏覽器設(shè)置無(wú)關(guān),縮放網(wǎng)頁(yè)并不會(huì)改變分辨率。
下面是根據(jù)屏幕分辨率,將用戶導(dǎo)向不同網(wǎng)頁(yè)的代碼。
if ((screen.width<=800) && (screen.height<=600)) {
window.location.replace('small.html');
} else {
window.location.replace('wide.html');
}
history對(duì)象主要用來(lái)操作瀏覽器URL的歷史記錄,可以通過(guò)參數(shù)向前,向后,或者向指定URL跳轉(zhuǎn)
常用的屬性如下:
接收一個(gè)整數(shù)數(shù)字或者字符串參數(shù):向最近的一個(gè)記錄中包含指定字符串的頁(yè)面跳轉(zhuǎn),
history.go('maixaofei.com')
當(dāng)參數(shù)為整數(shù)數(shù)字的時(shí)候,正數(shù)表示向前跳轉(zhuǎn)指定的頁(yè)面,負(fù)數(shù)為向后跳轉(zhuǎn)指定的頁(yè)面
history.go(3) //向前跳轉(zhuǎn)三個(gè)記錄
history.go(-1) //向后跳轉(zhuǎn)一個(gè)記錄
JavaScript提供四個(gè)URL的編碼/解碼方法。
getComputedStyle方法接受一個(gè)HTML元素作為參數(shù),返回一個(gè)包含該HTML元素的最終樣式信息的對(duì)象。
window.matchMedia方法用來(lái)檢查CSS的mediaQuery語(yǔ)句。
alert()、prompt()、confirm()都是瀏覽器用來(lái)與用戶互動(dòng)的方法。它們會(huì)彈出不同的對(duì)話框,要求用戶做出回應(yīng)。
需要注意的是,alert()、prompt()、confirm()這三個(gè)方法彈出的對(duì)話框,都是瀏覽器統(tǒng)一規(guī)定的式樣,是無(wú)法定制的。
alert方法彈出的對(duì)話框,只有一個(gè)“確定”按鈕,往往用來(lái)通知用戶某些信息。
// 格式
alert(message);
// 實(shí)例
alert("Hello World");
用戶只有點(diǎn)擊“確定”按鈕,對(duì)話框才會(huì)消失。在對(duì)話框彈出期間,瀏覽器窗口處于凍結(jié)狀態(tài),如果不點(diǎn)“確定”按鈕,用戶什么也干不了。
prompt方法彈出的對(duì)話框,在提示文字的下方,還有一個(gè)輸入框,要求用戶輸入信息,并有“確定”和“取消”兩個(gè)按鈕。它往往用來(lái)獲取用戶輸入的數(shù)據(jù)。
// 格式
var result = prompt(text[, default]);
// 實(shí)例
var result = prompt('您的年齡?', 25)
上面代碼會(huì)跳出一個(gè)對(duì)話框,文字提示為“您的年齡?”,要求用戶在對(duì)話框中輸入自己的年齡(默認(rèn)顯示25)。
prompt方法的返回值是一個(gè)字符串(有可能為空)或者null,具體分成三種情況:
用戶輸入信息,并點(diǎn)擊“確定”,則用戶輸入的信息就是返回值。
用戶沒(méi)有輸入信息,直接點(diǎn)擊“確定”,則輸入框的默認(rèn)值就是返回值。
用戶點(diǎn)擊了“取消”(或者按了Escape按鈕),則返回值是null。
prompt方法的第二個(gè)參數(shù)是可選的,但是如果不提供的話,IE瀏覽器會(huì)在輸入框中顯示undefined,Chrome會(huì)返回空字符串""。因此,最好總是提供第二個(gè)參數(shù),作為輸入框的默認(rèn)值。
confirm方法彈出的對(duì)話框,除了提示信息之外,只有“確定”和“取消”兩個(gè)按鈕,往往用來(lái)征詢用戶的意見(jiàn)。
// 格式
var result = confirm(message);
// 實(shí)例
var result = confirm("你最近好嗎?");
上面代碼彈出一個(gè)對(duì)話框,上面只有一行文字“你最近好嗎?”,用戶選擇點(diǎn)擊“確定”或“取消”。
confirm方法返回一個(gè)布爾值,如果用戶點(diǎn)擊“確定”,則返回true;如果用戶點(diǎn)擊“取消”,則返回false。
給大家分享我收集整理的各種學(xué)習(xí)資料,前端小白交學(xué)習(xí)流程,入門教程等回答-下面是學(xué)習(xí)資料參考。
前端學(xué)習(xí)交流、自學(xué)、學(xué)習(xí)資料等推薦 - 知乎
、背景
最近在做一些東西的時(shí)候,遇到一個(gè)需要Springmvc后臺(tái)接收l(shuí)ist類型數(shù)據(jù)的需求,幾經(jīng)輾轉(zhuǎn)才完美解決了這個(gè)問(wèn)題,今天記下來(lái)方便以后使用,也分享給需要的小伙伴們~
二、實(shí)現(xiàn)方式
實(shí)現(xiàn)方式一
前端頁(yè)面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>測(cè)試</title> 8 </head> 9 <body> 10 <input type="button" name="request" value="請(qǐng)求后臺(tái)" style="width:200px;height:50px;background-color:red;margin-bottom:20px;"> 11 <div name="rs"></div> 12 <input type="checkbox" name="se" value="1">hafiz.zhang<br/> 13 <input type="checkbox" name="se" value="2">jack.chen<br/> 14 <input type="checkbox" name="se" value="3">lili.wang<br/> 15 <script type="text/javascript"> 16 17 $("input[name='request']").click(function(){ 18 var data = []; 19 $("input[name='se']").each(function(){ 20 if($(this).prop("checked")) { 21 data.push($(this).val()); 22 } 23 }); 24 var json_data = JSON.stringify(data); 25 $.ajax({ 26 type:"post", 27 url:$.wap.url + "/test/index", 28 contentType:"application/json", 29 data:json_data , 30 dataType:"json", 31 success:function(data){ 32 var str=""; 33 for(var i = 0; i < data.length; i++) { 34 str += ";name=" + data[i]; 35 } 36 $("div[name='rs']").html(str); 37 }, 38 error:function(){ 39 alert("出錯(cuò)啦"); 40 } 41 }); 42 }); 43 </script> 44 </body> 45 </html>
后臺(tái)接收
1 package com.hafiz.www.controller; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestBody; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMethod; 10 import org.springframework.web.bind.annotation.ResponseBody; 11 12 @Controller 13 @RequestMapping("/test") 14 public class TestController { 15 @RequestMapping(value = "/index", method = RequestMethod.POST) 16 @ResponseBody 17 public List<Integer> test(@RequestBody ArrayList<Integer> ids){ 18 System.out.println("List==" + ids); 19 return ids; 20 } 21 }
注意:這種方法只適用于POST方法提交,(上面代碼中標(biāo)紅的是必不可少的代碼)如果使用get方法會(huì)出現(xiàn)如下圖所示的錯(cuò)誤
這是因?yàn)間et方式的參數(shù)中的雙引號(hào)會(huì)被編碼,導(dǎo)致傳到后臺(tái)的不再是json串格式,所以解析出錯(cuò)。
實(shí)現(xiàn)方式二
前端頁(yè)面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>測(cè)試</title> 8 </head> 9 <body> 10 <input type="button" name="request" value="請(qǐng)求后臺(tái)" style="width:200px;height:50px;background-color:red;margin-bottom:20px;"> 11 <div name="rs"></div> 12 <input type="checkbox" name="se" value="1">hafiz.zhang<br/> 13 <input type="checkbox" name="se" value="2">jack.chen<br/> 14 <input type="checkbox" name="se" value="3">lili.wang<br/> 15 <script type="text/javascript"> 16 17 $("input[name='request']").click(function(){ 18 var data = []; 19 $("input[name='se']").each(function(){ 20 if($(this).prop("checked")) { 21 data.push($(this).val()); 22 } 23 }); 24 $.ajax({ 25 type:"get", 26 url:$.wap.url + "/test/index", 27 data:{"datas":data},//或者data:{"datas[]":data} 28 dataType:"json", 29 success:function(data){ 30 var str=""; 31 for(var i = 0; i < data.length; i++) { 32 str += ";name=" + data[i]; 33 } 34 $("div[name='rs']").html(str); 35 }, 36 error:function(){ 37 alert("出錯(cuò)啦"); 38 } 39 }); 40 }); 41 </script> 42 </body> 43 </html>
后臺(tái)接收,指定參數(shù)名必須以數(shù)組方式,如:@RequestParam("datas[]")
1).通過(guò)ArrayList接收
1 package com.hafiz.www.controller; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import org.springframework.web.bind.annotation.ResponseBody; 11 12 @Controller 13 @RequestMapping("/test") 14 public class TestController { 15 @RequestMapping(value = "/index", method = RequestMethod.GET) 16 @ResponseBody 17 public List test(@RequestParam("datas[]") ArrayList<Integer> ids){ 18 System.out.println("List==" + ids); 19 return ids; 20 } 21 }
2).通過(guò)數(shù)組進(jìn)行接收
1 package com.hafiz.www.controller; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import org.springframework.web.bind.annotation.ResponseBody; 11 12 @Controller 13 @RequestMapping("/test") 14 public class TestController { 15 @RequestMapping(value = "/index", method = RequestMethod.POST) 16 @ResponseBody 17 public Integer[] test(@RequestParam("datas[]") Integer[] ids){ 18 System.out.println("ids==" + ids); 19 return ids; 20 } 21 }
注意:
1.這種方式對(duì)于get和post方式的請(qǐng)求同樣都適用....
2.以上兩種實(shí)現(xiàn)方式傳到后臺(tái)的數(shù)據(jù)不能為null,否則會(huì)報(bào)Http 400錯(cuò)誤。
實(shí)現(xiàn)方式三
前端頁(yè)面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 3 <html> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 6 <title>測(cè)試</title> 7 </head> 8 <body> 9 <input type="button" name="request" value="請(qǐng)求后臺(tái)" 10 style="width:200px;height:50px;background-color:red;margin-bottom:20px;"> 11 <div name="rs"></div> 12 <input type="checkbox" name="se" value="1">hafiz.zhang<br/> 13 <input type="checkbox" name="se" value="2">jack.chen<br/> 14 <input type="checkbox" name="se" value="3">lili.wang<br/> 15 <script type="application/javascript" src="js/jquery-1.11.1.min.js"></script> 16 <script type="text/javascript"> 17 18 $("input[name='request']").click(function () { 19 var data = []; 20 $("input[name='se']").each(function () { 21 if ($(this).prop("checked")) { 22 data.push($(this).val()); 23 } 24 }); 25 $.ajax({ 26 type: "post", 27 url: "/test/index", 28 data: {"datas": data.join()} 29 dataType: "json", 30 success: function (data) { 31 var str = ""; 32 for (var i = 0; i < data.length; i++) { 33 str += ";name=" + data[i]; 34 } 35 $("div[name='rs']").html(str); 36 }, 37 error: function () { 38 alert("出錯(cuò)啦"); 39 } 40 }); 41 }); 42 </script> 43 </body> 44 </html>
后端代碼
1)通過(guò)數(shù)組接收
1 package com.hafiz.www.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestMethod; 6 import org.springframework.web.bind.annotation.RequestParam; 7 import org.springframework.web.bind.annotation.ResponseBody; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 /** 13 * Desc:測(cè)試控制器 14 * Created by hafiz.zhang on 2017/7/2. 15 */ 16 @Controller 17 @RequestMapping("/test") 18 public class TestController { 19 @RequestMapping(value = "/index", method = RequestMethod.POST) 20 @ResponseBody 21 public Integer[] test(@RequestParam("datas") Integer[] ids) { 22 System.out.println("ids=" + ids); 23 return ids; 24 } 25 }
2).通過(guò)List接收
package com.hafiz.www.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; /** * Desc:測(cè)試控制器 * Created by hafiz.zhang on 2017/7/2. */ @Controller @RequestMapping("/test") public class TestController { @RequestMapping(value = "/index", method = RequestMethod.POST) @ResponseBody public List test(@RequestParam("datas") List<Integer> ids) { System.out.println("ids=" + ids); return ids; } }
這種方式即使沒(méi)有選中任何復(fù)選框進(jìn)行提交,也不會(huì)報(bào)錯(cuò)!
對(duì)于想要前端傳自定義對(duì)象數(shù)組到后端,以上的方式就不適用了,那么解決辦法是什么呢?
如果你有更好的實(shí)現(xiàn)方式,希望可以拿來(lái)分享。。。。
三、總結(jié)
1.實(shí)現(xiàn)方式一只對(duì)post方法有效,且比較繁瑣,不推薦!
2.實(shí)現(xiàn)方式二要求后端接收的時(shí)候必須聲明參數(shù)為數(shù)組,但可以使用數(shù)組或者list進(jìn)行接收參數(shù),如:@RequestParam("datas[]"),前端使用data:{"datas":data}或data:{"datas[]":data}都可以!且post和get方法都適用。但是不能傳空數(shù)組,限制也比較多,也不太推薦。
3.實(shí)現(xiàn)方式三只需要前端傳值的時(shí)候使用數(shù)組的join()方法,為空數(shù)組也不會(huì)報(bào)錯(cuò),配置簡(jiǎn)單,要求少,且支持使用數(shù)組和list進(jìn)行接收參數(shù),比較推薦!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。