JSP,html与javascript

你寫了一個JSP網頁,使用Big5編碼:
<%@ page contentType="text/html; charset=Big5" 
    pageEncoding="Big5"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Big5">
<title>JSP 網頁</title>
</head>
<body>
    名稱:<input type="text" name="name" value="${name}">
</body>
</html>

其中${name}會是資料庫中撈取出來的名稱,放在請求範圍屬性中再轉發至這個JSP頁面,如果實際上資料庫中的名稱是「王大犇」,在伺服端的JVM中撈取出來的名稱也確認是正確的顯示,但再經由這個JSP網頁,卻會是亂碼:


這是自然地,因為你的網頁採Big5編碼,對瀏覽器而言,看到的HTML是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Big5">
<title>JSP 網頁</title>
</head>
<body>
    名稱:<input type="text" name="name" value="王大?">
</body>
</html>

在 
Big 5 網頁難字  中介紹過,你可以將特殊字元用實體編號表示,所以你可以在伺服端JVM中使用StringEscapeUtils.escapeHtml()之類的程式庫,將「王大犇」處理為「&#29579;&#22823;&#29319;」:
request.setAttribute("name", StringEscapeUtils.escapeHtml("王大犇"));

如此看到的就會是正確的字元:


這是因為瀏覽器看到:
名稱:<input type="text" name="name" value="&#29579;&#22823;&#29319;">

再將「&#29579;&#22823;&#29319;」轉為實際的「王大犇」。然而,如果你這麼撰寫:
<%@ page contentType="text/html; charset=Big5" 
    pageEncoding="Big5"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <script type="text/javascript">
        window.onload = function() {
            document.getElementById('name').value = '${name}';
        };
    </script>
<meta http-equiv="Content-Type" content="text/html; charset=Big5">
<title>JSP 網頁</title>
</head>
<body>
    名稱:<input id="name" type="text" name="name">
</body>
</html>

如果${name}是將「王大犇」處理為「&#29579;&#22823;&#29319;」的結果,那你會看到:


這個問題在   JavaScript 編碼基礎 中略談過,瀏覽器對於收到的HTML會進行剖析,這是實體編號被剖析為對應字元的時間點,這也是為什麼:
名稱:<input type="text" name="name" value="&#29579;&#22823;&#29319;">

最後會看到「王大犇」,瀏覽器完成HTML剖析後,會
建立JavaScript環境中對應的DOM物件,如果你直接將字串指定給DOM的特性,那就會以實際的字串值設定給DOM特性,而不會再經由剖析,不過  JavaScript 編碼基礎 提過,innerHTML特性是個例外,指定給innerHTML的字串,會嘗試再進行HTML剖析,所以如果你這麼撰寫:
<%@ page contentType="text/html; charset=Big5" 
    pageEncoding="Big5"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <script type="text/javascript">
        window.onload = function() {
            var span = document.createElement('span');
            span.innerHTML = '${name}';
            document.getElementById('name').value = span.innerHTML;
        };
    </script>
<meta http-equiv="Content-Type" content="text/html; charset=Big5">
<title>JSP 網頁</title>
</head>
<body>
    名稱:<input id="name" type="text" name="name">
</body>
</html>

那你就會看到正確的「王大犇」。

你會想,誰會那麼無聊,使用JSP將字串產生為JavaScript,再用JavaScript指定給輸入欄位呢?有的時候,尤其是維護舊系統為主的公司,有些部份是你可以修改的,但有些剖份是你不能修改的(例如也許是另一個部份負責的子系統),就會遇到類似的情況。

例如,也許另一個子系統傳回的字串一徑作實體編號,
你的JSP中,使用Ajax進行查詢, 像是某個查詢人名,另一個子系統直接將查得的人名作實體編號傳回以下結果:
&#29579;&#22823;&#29319;

如果你這麼撰寫:
        request.onreadystatechange = function() {
            if(request.readyState === 4) {
                if(request.status === 200) {
                    document.getElementById('name').value = request.responseText;
                }
            }
        };

那文字欄位就會出現「&#29579;&#22823;&#29319;」,但如果你這麼撰寫:
<%@ page contentType="text/html; charset=Big5" 
    pageEncoding="Big5"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <script type="text/javascript">
    window.onload = function() {
        var xhr = window.XMLHttpRequest && 
              (window.location.protocol !== 'file:' 
                  || !window.ActiveXObject) ?
               function() {
                   return new XMLHttpRequest();
               } :
               function() {
                  try {
                     return new ActiveXObject('Microsoft.XMLHTTP');
                  } catch(e) {
                     throw new Error('XMLHttpRequest not supported');
                  }
               };
        var request = xhr();
        request.onreadystatechange = function() {
            if(request.readyState === 4) {
                if(request.status === 200) {
                    var span = document.createElement('span');
span.innerHTML = request.responseText;
document.getElementById('name').value = span.innerHTML; } } }; request.open('GET', 'response'); request.send(null); }; </script> <meta http-equiv="Content-Type" content="text/html; charset=Big5"> <title>JSP 網頁</title> </head> <body> 名稱:<input id="name" type="text" name="name"><br> </body> </html>

那就可以得到正確的顯示結果。事實上,這些作法,只不過是
 Servlet 中文處理(Tomcat Big 5 網頁難字 JSP 的轉譯 JavaScript 編碼基礎   等基礎觀念的綜合應用,許多程式設計人員在這些基礎不足下,自然就無法變化應用。

再看一個學員來信的例子:
問:若db的資料內容若有單引號或雙引號,撈出來會造成html顯示不正常,怎麼解決呢?

如果有個輸入欄位:
<input type="text" value="${data}">

如果資料庫中的資料有雙引號,例如123"456結果就會是:
<input type="text" value="123"456">

這個HTML當然有問題,也許你會想,那就這樣:
<input type="text" value='${data}'>

如果資料庫中的資料有雙引號,例如123"456結果就會是:
<input type="text" value='123"456'>

但現在的情況中,資料庫中的資料是雙引號或單引號都有,如果資料實際上是123'456,你怎麼辦?

簡單的解決方式之一可以用JSTL,例如:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <%
            String text1 = "test'test";
            String text2 = "test\"test";
        %>
        <input type="text" value="<c:out value="<%= text1 %>"/>"><br>
        <input type="text" value="<c:out value="<%= text2 %>"/>">
    </body>
</html>

<c:out>預設escapeXML是true,所以可解決問題,但這位學員又有問題了:
問:不過還真的有一好沒兩好,當我們想要 document.getElementById('xxx').value 給值的時候,卻會老老實實的顯示html內碼
ex.會顯示 123&#039;456 或 123&#034;456

我不太知道他要用<c:out>產生值給
JavaScript 的原因,但要同時滿足兩個需求也非不行:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
        <%
            String text1 = "test'test";
            String text2 = "test\"test";
        %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
        <script type="text/javascript">
            window.onload = function() {
                document.getElementById('i3').value =
                           document.getElementById('i1').value;

                document.getElementById('i4').value =
                           document.getElementById('i2').value;


            };
        </script>
    </head>
    <body>
        <h1>Hello World!</h1>
        <input id="i1" type="hidden" value="<c:out value="<%= text1 %>"/>"><br>
        <input id="i2" type="hidden" value="<c:out value="<%= text2 %>"/>"><br>

        <input id="i3" type="text"><br>
        <input id="i4" type="text">
    </body>
</html>

使用hidden欄位也可以,或者你也可以像先前用動態產生DOM元素的方式,這都是先前例子的再變化應用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值