JSON in Java und Jackson Teil ③ Betten Sie JSON in HTML ein und verwenden Sie es aus JavaScript

Einführung

Ich denke, bei der Verwendung von JSON gibt es viele Fälle, in denen Daten von JavaScript über Ajax gesendet und empfangen werden. Es gibt jedoch Fälle, in denen Sie JSON-Daten empfangen und in JavaScript verwenden möchten, wenn HTML vom Server empfangen wird. In diesem Fall werden JSON-Daten in den vom Server zurückgegebenen HTML-Code eingebettet und als JavaScript-Objekt gelesen. Bei der Verwendung von PHP wurde ein Beispiel unter Einbetten von JSON-Daten in HTML und deren Verwendung aus JavaScript beschrieben, aber unser Java (Servlet / Da es keinen Fall von JSP gab, bleibt das Ergebnis des Kampfes hier.

Umgebung

Machen wir es ohne nachzudenken ⇒ Fehler

Serverseite

Die Serverseite ist wie folgt. "<" Und ">" können wie bei vorherige als HTML-Tags interpretiert werden, sodass die Konvertierung der Unicode-Escape-Sequenz unverändert bleibt. Es gibt. Der Unterschied zum vorherigen Zeitpunkt besteht darin, dass die JSON-Zeichenfolge als Parameter von HttpRequest gespeichert und von JSP verarbeitet wird. Details werden auf der Client-Seite erklärt. Als mittlere Daten setze ich \ am Ende der Daten wie `" Programmer "⇒" Programmer \ "".

ServletTest2.java


package servletTest;

import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@WebServlet("/helloworld2")
public class ServletTest2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    	//Legen Sie einen Wert in einem Java-Objekt fest
    	JsonBean jsonBean = new JsonBean();
    	jsonBean.setId(1);
    	jsonBean.setName("kimisyo");
    	List<String> datas = new ArrayList<>();
    	datas.add("Programmer\\");
    	datas.add("Data Scientist<script>alert('hello!')</script>");
    	jsonBean.setDatas(datas);

    	ObjectMapper mapper = new ObjectMapper();
    	mapper.getFactory().setCharacterEscapes(new CustomCharacterEscapes());

    	//Vom Java-Objekt in JSON konvertieren
    	String testJson = mapper.writeValueAsString(jsonBean);

    	//Stellen Sie die JSON-Zeichenfolge auf Anforderung ein
    	request.setAttribute("jsonStr", testJson);
    	ServletContext sc = getServletContext();
    	sc.getRequestDispatcher("/clientTest2.jsp").forward(request, response);

    }
}

Client-Seite

Die Client-Seite beschreibt den Prozess in jsp. Der als Parameter von HttpRequest festgelegte JSON-Zeichenkettensatz wird vorübergehend in einer Java-Variablen gespeichert und im JavaScript-Argument JSON Parse festgelegt. Wenn dies funktioniert, kann JSON über ein Objekt namens data verarbeitet werden.

clientTest2.jsp


<%@ page contentType="text/html; charset=UTF-8"%>
<%
	String jsonStr = (String)request.getAttribute("jsonStr");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<script>
	var data = JSON.parse('<%=jsonStr%>');
     alert(data.datas);
</script>
</head>
<body>
</body>
</html>

Fehlersituation

Wenn ich das Servlet oben ausführe, ist das Zeichen `SCRIPT1014: in JSON.parse falsch. Ich erhalte einen JavaScript-Fehler `` (überprüfen Sie auf der IE-Konsole). Der HTML-Code, der schließlich an den Browser ausgegeben wird, lautet wie folgt. Das \ im JSON wurde von Jackson ordnungsgemäß nach \\ maskiert, und die "<" und ">" wurden in eine Unicode-Escape-Sequenz konvertiert. Auf den ersten Blick sieht es gut aus.

Lassen Sie uns nun darüber nachdenken, was schief gelaufen ist.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<script>
	var data = JSON.parse('{"id":1,"name":"kimisyo","datas":["Programmer\\","Data Scientist\u003Cscript\u003Ealert(\u0027hello!\u0027)\u003C\u002Fscript\u003E"]}');
	alert(data.datas);
</script>
</head>
<body>
	<div id="test"></div>
</body>
</html>

Fehlerursache

Die Ursache des Fehlers ist das Weglassen der Escape-Funktion der JavaScript-Zeichenfolge. In JavaScript wird \ als Escapezeichen verwendet. Daher wird `" Programmer \\ "" als `" Programmer \ "` als JavaScript-Zeichenfolge erkannt. Dies wird an JSON.Parse übergeben, aber selbst in JSON muss das Zeichen selbst von "" wie "\" maskiert werden, damit es als ungültige JSON-Daten behandelt wird.

Gegenmaßnahmen

Als Gegenmaßnahme entkommen Sie der Verarbeitung für JavaScript und geben Sie sie dann an das Argument von JSON.parse weiter. Die modifizierte Quelle wird unten beschrieben. Hier ist als Escapezeichen der JavaScript-Zeichenfolge der Prozess zum Escapezeichen von "" und "'" enthalten.

clientTest2.jsp


<%@ page contentType="text/html; charset=UTF-8"%>
<%
	String jsonStr = (String)request.getAttribute("jsonStr");
	jsonStr = jsonStr.replace("\\", "\\\\");
	jsonStr = jsonStr.replace("'", "\\'");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<script>
	var data = JSON.parse('<%=jsonStr%>');
     alert(data.datas);
</script>
</head>
<body>
</body>
</html>

Dadurch wurde die JSON-Zeichenfolge korrekt in das JSON-Objekt geladen. Wenn Sie für JavaScript "" maskieren, wird das in der konvertierten Unicode-Escape-Sequenz verwendete "" (z. B. "\ u0027") ebenfalls maskiert und in "\\ u0027" konvertiert. Sie könnten sich fragen, ob es verrückt werden wird. Tatsächlich wird "\\ u0027" von JavaScript als "\ u0027" interpretiert und dem Argument von JSON.parse übergeben, sodass es auf der JSON-Seite als Unicode-Escape-Sequenz interpretiert wird. Mit anderen Worten, in JSON wird dieselbe Form wie im Fall der vorherigen XSS-Gegenmaßnahme geladen, und dies ist vielmehr die beabsichtigte Operation. Vor dem Escape für JavaScript wurde es tatsächlich als Unicode-Escape-Sequenz auf der HTML-Seite interpretiert. Nun, es ist tief.

abschließend

Immerhin war es eine nüchterne Pointe, die eine JavaScript-Flucht war. Als ich mit dieser Serie anfing, wollte ich diesen Artikel schreiben, deshalb möchte ich ihn vorerst abschließen.

Übrigens, im Beispiel auf der Serverseite dieses Artikels erkläre ich die Verwendung von Servlet ohne Verwendung des WEB-Frameworks, weil ich Servlet nur separat verwenden kann. Ich möchte Servlet nicht verwenden, Elemente, die nicht mit dem Thema dieses Artikels zusammenhängen Ich wollte nur die wesentlichen Teile ausschließen und mich darauf konzentrieren.

Referenz

Recommended Posts

JSON in Java und Jackson Teil ③ Betten Sie JSON in HTML ein und verwenden Sie es aus JavaScript
JSON in Java und Jackson Teil 1 Gibt JSON vom Server zurück
JSON mit Java und Jackson Teil 2 XSS-Maßnahmen
Konvertieren Sie JSON und YAML in Java (mit Jackson und SnakeYAML)
Konvertieren Sie Java Enum Enumeration und JSON von und nach Jackson
[Java] Konvertieren Sie JSON in Java und Java in JSON-How to use GSON and Jackson-
Verwendung von JSON-Daten in der WebSocket-Kommunikation (Java, JavaScript)
Implementieren Sie die Java-Schnittstelle in der JRuby-Klasse und rufen Sie sie von Java aus auf
Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 2-Programmierung)
Rufen Sie Java-Methoden aus JavaScript auf, das in Java ausgeführt wird
Verwenden Sie "Rhino", das JavaScript in Java ausführt
[Java] Json von der URL mit der Standard-API (javax.script) abrufen und verarbeiten
Beispielcode zum Serialisieren und Deserialisieren von Java Enum-Enumerationen und JSON in Jackson
Gradle generiert automatisch eine Versionsnummer aus git und verwendet diese in Java
[Java] Geben Sie das Ergebnis von ffprobe -show_streams in JSON aus und ordnen Sie es einem Objekt in Jackson zu
Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 1-Build) (OpenCV-3.4.4)
Java: Laden Sie die Datei herunter und speichern Sie sie an dem im Dialogfeld [Use HttpClient] ausgewählten Speicherort.
Unterschiede beim Schreiben von Java-, C # - und Javascript-Klassen
Erfassen und speichern Sie die Selen-Installation in Java
Java und JavaScript
Generieren Sie OffsetDateTime aus Clock und LocalDateTime in Java
[Android-Entwicklung] Holen Sie sich mit Java Bilder vom Server und legen Sie sie in ImageView fest! !!
Einbetten von JavaScript-Variablen in HTML mit Thymeleaf
Schreiben Sie eine Klasse in Kotlin und nennen Sie sie in Java
Subtrahieren Sie Enum-Konstanten von Zeichenfolgen und Werten in Java zurück
Verwendung von Abstract Class und Interface in Java richtig
Lesen Sie JSON in Java
Verwenden Sie java.time mit Jackson
Verwenden Sie OpenCV mit Java
POST JSON in Java
Erstellen Sie JSON in Java
Verwenden Sie PreparedStatement in Java
Was ich in Java gelernt habe (Teil 4) Bedingte Verzweigung und Wiederholung
Aufrufen und Verwenden der API in Java (Spring Boot)
[Kotlin] Holen Sie sich Java Constructor / Method von KFunction und rufen Sie es auf
Korrigieren Sie den Zeichencode in Java und lesen Sie von der URL
Gründe, Servlet und JSP in der Java-Entwicklung getrennt zu verwenden
Ruft Attribute und Werte aus einer XML-Datei in Java ab
[Java] JSON-Kommunikation mit Jackson
Versuchen Sie, JavaScript in Java aufzurufen
Java und Iterator Teil 1 Externe Iterator Edition
Verwenden Sie Ruby-Variablen in Javascript.
Apache Hadoop und Java 9 (Teil 1)
POST Json in Java ~ HttpURLConnection ~
Json-Serialisierung / Deserialisierung in Java 1.4
JavaScript von Java aus gesehen
Installieren Sie das memcached Plugin unter MySQL und greifen Sie von Java aus zu
Was ich in Java gelernt habe (Teil 1) Java-Entwicklungsablauf und Überblick
[Java8] Angemessene Verwendung von Compareable und Comparator unter dem Gesichtspunkt der Mitarbeitersortierung
[Android] Konvertieren Sie Map in JSON mit GSON mit Kotlin und Java
Schritte zum Installieren von Maven auf einem Mac und zur Verwendung mit Eclipse