實現描述:js前端頁面保存到從數據庫字段傳來經java處理的值後,再從頁面傳值給java代碼再保存到數據庫字段;最後保存到數據庫字段的值與原數據庫查詢到的字段值一致?
在jsp程序裏js函數中的變量很多時候需要從java變量傳值,而java變量中含有js對應的特殊字符對js造成語法性破壞。以下作者就實際處理情況做一總結分析:
一。
JavaScript 中也有一些需要特殊處理的字符,如果直接將它們嵌入 JavaScript 代碼中,JavaScript 程序結構將會遭受破壞,甚至被嵌入一些惡意的程序。下面列出了需要轉義的特殊 JavaScript 字符:
- ' :/'
- " :/"
- / ://
- 走紙換頁: /f
- 換行:/n
- 換欄符:/t
- 回車:/r
- 回退符:/b
我們通過一個具體例子演示動態變量是如何對 JavaScript 程序進行破壞的。假設我們有一個 JavaScript 數組變量,其元素值通過一個 Java List 對象提供,下面是完成這一操作的 JSP 代碼片斷:
jsTest.jsp:未對 JavaScript 特殊字符進行處理
<%@ page language="java" contentType="text/html; charset=utf-8"%> <jsp:directive.page import="java.util.*"/> <% List textList = new ArrayList(); textList.add("/";alert();j=/"");%> <script> var txtList = new Array(); <% for ( int i = 0 ; i < textList.size() ; i++) { %> txtList[<%=i%>] = "<%=textList.get(i)%>"; ① 未對可能包含特殊 JavaScript 字符的變量進行處理 <% } %></script> |
當客戶端調用這個 JSP 頁面後,將得到以下的 HTML 輸出頁面:
<script> var txtList = new Array(); txtList[0] = "";alert();j="";
① 本來是希望接受一個字符串,結果被植入了一段JavaScript代碼 </script> |
由於包含 JavaScript 特殊字符的 Java 變量直接合併到 JavaScript 代碼中,我們本來期望 ① 處所示部分是一個普通的字符串,但結果變成了一段 JavaScript 代碼,網頁將彈出一個 alert 窗口。想像一下如果粗體部分的字符串是“";while(true)alert();j="”時會產生什麼後果呢?
因此,如果網頁中的 JavaScript 代碼需要通過拼接 Java 變量動態產生時,一般需要對變量的內容進行轉義處理,可以通過 Spring 的 JavaScriptUtils 完成這件工作。下面,我們使用 JavaScriptUtils 對以上代碼進行改造:
<%@ page language="java" contentType="text/html; charset=utf-8"%> <jsp:directive.page import="java.util.*"/> <jsp:directive.page import="org.springframework.web.util.JavaScriptUtils"/> <% List textList = new ArrayList(); textList.add("/";alert();j=/"");%> <script> var txtList = new Array(); <% for ( int i = 0 ; i < textList.size() ; i++) { %> ① 在輸出動態內容前事先進行轉義處理 txtList[<%=i%>] = "<%=JavaScriptUtils.javaScriptEscape(""+textList.get(i))%>"; <% } %> </script> |
通過轉義處理後,這個 JSP 頁面輸出的結果網頁的 JavaScript 代碼就不會產生問題了:
<script> var txtList = new Array(); txtList[0] = "/";alert();j=/"";
① 粗體部分僅是一個普通的字符串,而非一段 JavaScript 的語句了 </script> |
其中JavaScriptUtils.javaScriptEscape(String s);函數可參考引自spring 框架web包代碼:
/****************************************************/
package org.springframework.web.util;
public class JavaScriptUtils {
/**
* Turn special characters into escaped characters conforming to JavaScript.
* Handles complete character set defined in HTML 4.01 recommendation.
* @param input the input string
* @return the escaped string
*/
public static String javaScriptEscape(String input) {
if (input == null) {
return input;
}
StringBuffer filtered = new StringBuffer(input.length());
char prevChar = '/u0000';
char c;
for (int i = 0; i < input.length(); i++) {
c = input.charAt(i);
if (c == '"') {
filtered.append("///"");
}
else if (c == '/'') {
filtered.append("//'");
}
else if (c == '//') {
filtered.append("////");
}
else if (c == '/') {
filtered.append("///");
}
else if (c == '/t') {
filtered.append("//t");
}
else if (c == '/n') {
if (prevChar != '/r') {
filtered.append("//n");
}
}
else if (c == '/r') {
filtered.append("//n");
}
else if (c == '/f') {
filtered.append("//f");
}
else {
filtered.append(c);
}
prevChar = c;
}
return filtered.toString();
}
}
/****************************************************/
二。對於js字符串含有【',"】單引號,雙引號的情況,且從java變量傳過來。則可對java字符串的單雙引號進行轉換-——》用‘"’代替雙引號用‘'’代替單引號,。
引出:
xhtml提供了一組特殊的字符
1,這些字符有時候會出現在文檔中,但不能以本身的樣式進行拼寫。
2,在某些情況下,這些字符在xhtml中具有特殊的意義,比如>、<和& 。
3,其他一些情況是某些字符在鍵盤上沒有對應的按鈕,比如表示攝氏溫度的小圓圈。
4,此外,還包括一些非換行空格,瀏覽器識別爲硬空格,瀏覽器不能像處理其他的多個空格那樣,排除一部分空格。
這些特殊的字符稱爲實體,這是瀏覽器對它們的命名。文檔中的實體可以在瀏覽器中通過對應的字符來替換。
下面列出了一些常用的字符實體:
字符 實體 含義
& & and的記號
< < 小於號
> > 大於號
" " 雙引號
' '或' 單引號
1/4 ¼ 四分之一
1/2 ½ 二分之一
3/4 ¾ 四分之三
。 ° 攝氏度
(space) 非換行空格
比如在onmouseover屬性中調用js函數,可能會出現英文雙/單引號“和'3層嵌套的情況,瀏覽器會發現語法錯誤,因此在函數參數中的”或'需用其實體替代了(好像還有其他辦法,這麼做是最簡單的)。
在IE下,'不能替代',只能用',“用"替代是沒問題的;在firefox下,'和'都能被正確地解釋爲單引號'。
結合以上一二的實例:
function saveDate(){
<%
String buffer = "??????"; //其中?內容來至數據庫某字段值含有單雙引號,其含有?值爲【"t'tt'ttt"ttt"1、定義:實際及時完成項數與計劃完成總項數的比率 2、計算公式:工作計劃完成率=實際及時完成項數/計劃完成總項數×100%"
】
buffer = JavaScriptUtils.javaScriptEscape(buffer);
//buffer = Tools.replaceAll(buffer,"///"",""");
buffer = Tools.replaceAll(buffer,"//'","'"); //單引號用 ' 代替
out.println("alldata["+seq+"]["+coll+"]=/""+buffer+"/";");
%>
}
//經過處理後,js前端保存到從數據庫字段傳來經java處理的值後,再從頁面傳值給java代碼再保存到數據庫字段;最好保存到數據庫字段的值與原數據庫查詢到的字段值一致了。