Tên thực thể phải ngay sau dấu '&' trong tham chiếu thực thể


91

Tôi muốn đặt trò chơi packman trên trang * .xhtml của mình. (Tôi đang sử dụng jsf 2 và primefaces 3.5)

Tuy nhiên,

khi tôi "dịch" trang html sang xhtml, tôi gặp lỗi ở tập lệnh này:

    <script>

    var el = document.getElementById("pacman");

    if (Modernizr.canvas && Modernizr.localstorage && 
        Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
      window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
    } else { 
      el.innerHTML = "Sorry, needs a decent browser<br /><small>" + 
        "(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
    }
  </script>

Tai dong:

if (Modernizr.canvas && Modernizr.localstorage && 

tôi có:

Tên thực thể phải ngay sau dấu '&' trong tham chiếu thực thể.

Bất cứ ý tưởng làm thế nào để khắc phục điều đó?

Câu trả lời:


219

Tất cả các câu trả lời được đăng cho đến nay đều đưa ra các giải pháp phù hợp, tuy nhiên không một câu trả lời nào có thể giải thích đúng nguyên nhân cơ bản của vấn đề cụ thể.

Khuôn mặt là một công nghệ dạng xem dựa trên XML sử dụng XHTML + XML để tạo ra đầu ra HTML. XML có năm ký tự đặc biệt được trình phân tích cú pháp XML xử lý đặc biệt:

  • < bắt đầu của một thẻ.
  • > cuối thẻ.
  • " đầu và cuối của một giá trị thuộc tính.
  • ' đầu và cuối thay thế của một giá trị thuộc tính.
  • &sự bắt đầu của một thực thể (kết thúc bằng ;).

Trong trường hợp &đó không được tiếp theo #(ví dụ &#160;, &#xA0;, vv), phân tích cú pháp XML được ngầm tìm kiếm một trong năm tên thực thể được xác định trước lt , gt, amp, quotapos, hoặc bất kỳ tên thực thể tự định nghĩa . Tuy nhiên, trong trường hợp cụ thể của bạn, bạn đang sử dụng &như một toán tử JavaScript, không phải như một thực thể XML. Điều này hoàn toàn giải thích lỗi phân tích cú pháp XML mà bạn gặp phải:

Tên thực thể phải ngay sau dấu '&' trong tham chiếu thực thể

Về bản chất, bạn đang viết mã JavaScript không đúng chỗ, một tài liệu XML thay vì một tệp JS, vì vậy, bạn nên thoát tất cả các ký tự đặc biệt của XML cho phù hợp. Các &phải được thoát ra như &amp;.

Vì vậy, trong trường hợp cụ thể của bạn,

if (Modernizr.canvas && Modernizr.localstorage && 

phải trở thành

if (Modernizr.canvas &amp;&amp; Modernizr.localstorage &amp;&amp;

để làm cho nó có giá trị XML.

Tuy nhiên, điều này làm cho mã JavaScript khó đọc và khó bảo trì hơn. Như đã nêu trong tài liệu tuyệt vời của Mạng nhà phát triển Mozilla Viết JavaScript cho XHTML , bạn nên đặt mã JavaScript trong khối dữ liệu ký tự (CDATA). Do đó, theo thuật ngữ JSF, đó sẽ là:

<h:outputScript>
    <![CDATA[
        // ...
    ]]>
</h:outputScript>

Trình phân tích cú pháp XML sẽ diễn giải nội dung của khối là dữ liệu ký tự "vani đơn giản" chứ không phải là XML và do đó diễn giải các ký tự đặc biệt XML "nguyên trạng".

Tuy nhiên, tốt hơn nhiều là chỉ cần đặt mã JS vào tệp JS của chính nó mà bạn đưa vào <script src>hoặc theo thuật ngữ JSF <h:outputScript>,.

<h:outputScript name="onload.js" target="body" />

(lưu ý rằng target="body"; theo cách này JSF sẽ tự động hiển thị <script>ở cuối <body>, bất kể <h:outputScript>nó nằm ở đâu, do đó đạt được hiệu quả tương tự như với window.onload$(document).ready(); vì vậy bạn không cần phải sử dụng chúng nữa trong tập lệnh đó)

Bằng cách này, bạn không cần phải lo lắng về các ký tự đặc biệt-XML trong mã JS của mình. Như một phần thưởng bổ sung, điều này mang lại cho bạn cơ hội để trình duyệt lưu vào bộ đệm tệp JS để tổng kích thước phản hồi nhỏ hơn.

Xem thêm:


Không nên! [CDATA [là một dòng nhận xét? Chỉ tò mò.
Nacho321

@ Nacho321: Chỉ khi loại nội dung được đặt sai thành application/xhtml+xmlthay vì text/html, điều này sẽ gây ra một số lỗi trong một số trình duyệt, chủ yếu là MSIE. Xem thêm tài liệu "Viết JavaScript cho XHTML". Trong JSF, bạn không cần phải làm như vậy nếu bạn sử dụng <f:view contentType="text/html">thay vì để cho JSF / trình duyệt web tự động đoán thực hiện công việc. Xem thêm stackoverflow.com/tags/xhtml/info
BalusC

LƯU Ý: Điều này không chỉ xảy ra đối với các hoạt động Javascipt (vì tôi sử dụng đúng &amp;&amp;trong câu lệnh if một dòng phía trên lỗi của tôi), mà còn xảy ra trên dòng nhận xét; lỗi của tôi đã được bật // TODO KevinC & Victor: some todo(bây giờ nó đã được đổi thành and..). Ngoài ra, cảm ơn rất nhiều cho bài đăng này. Tôi đã xem qua nó trước đây như một bản sửa lỗi cho vấn đề tương tự như OP.
Kevin Cruijssen

câu trả lời của bạn là sai. nó phải là & amp; thay vì & amp; & amp;
sôi nổi-

1
@ funky-nd: Tôi đoán bạn đã nhầm lẫn nó với & amp; amp ;. Bây giờ đọc lại câu trả lời với điều này trong tâm trí.
BalusC

14

Bạn cần thêm thẻ CDATA bên trong thẻ script, trừ khi bạn muốn chuyển qua và thoát tất cả các ký tự XHTML theo cách thủ công (ví dụ: &cần phải trở thành &amp;). Ví dụ:

<script>
//<![CDATA[
var el = document.getElementById("pacman");

if (Modernizr.canvas && Modernizr.localstorage && 
    Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
  window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
} else { 
  el.innerHTML = "Sorry, needs a decent browser<br /><small>" + 
    "(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
}
//]]>
</script>

12

Trình phân tích cú pháp đang mong đợi một số nội dung HTML, vì vậy nó được coi &là sự khởi đầu của một thực thể, chẳng hạn như &egrave;.

Sử dụng giải pháp này:

<script type="text/javascript">
// <![CDATA[
Javascript code here
// ]]>
</script>

vì vậy bạn chỉ định rằng mã không phải là văn bản HTML mà chỉ là dữ liệu được sử dụng nguyên trạng.



2

Nếu bạn sử dụng XHTML, vì lý do nào đó, hãy lưu ý rằng XHTML 1.0 C 4 cho biết: “Hãy sử dụng tập lệnh bên ngoài nếu tập lệnh của bạn sử dụng <hoặc & hoặc]]> hoặc -.” Nghĩa là, không nhúng mã script vào bên trong một scriptphần tử mà hãy đặt nó vào một tệp JavaScript riêng và tham chiếu đến nó <script src="foo.js"></script>.


0

Đề phòng trường hợp ai đó từ Blogger đến, tôi đã gặp sự cố này khi sử dụng Beautifytiện ích mở rộng trong VSCode. Đừng sử dụng nó, đừng beautifynó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.