1

I'm trying to achieve the following: A simple Java Spring application, after receiving a GET request, sends me an HTML page with a form. When the button is pressed in this form, there is a POST request with an XML content sent back to the Spring app, which, in turn, responds with an HTML page. I would like to be able to display this response as a proper page in a browser, including all the scripts being downloaded and fully functional.

The form HTML page:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <meta charset="UTF-8" />
    <title>Request Report Form</title>
</head>
<body>
<form method="post" action="">
    <script>
        function sendXml()
        {
            event.preventDefault();
            const request = '<?xml version="1.0" encoding="UTF-8"?>\n' +
            <!-- skip -->
            $.ajax({
                type: 'POST',
                url: url,
                dataType: 'html',
                data: request,
                contentType: 'application/xml;'
            }).done(function (data) {
                $("html").html(data);
            }).fail(function (data) {
                $("html").html(data.responseText);
            });
        }
    </script>

</form>

</body>
</html>

The $("html").html(data); part above is supposed to replace the current page's content with the content received from the server, as far as I understand. But the page is not being displayed. There is an error message in the browser's console: "TypeError: n.head is null", it seems to have to do with JQuery, see the image link.

JQuery error screenshot

My questions are, why does JQuery kicks in and what is it trying to do? And how do I fix this error? I don't know much about frontend side of development, so please go easy on me ;-)

Edit

Just realised that my first question is moot, I am trying to display the response page using JQuery, so obviously, it kicks in at that point. But the call fails for some reason.

The content of the response from the server that I'd like to see rendered by the browser:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Progress Report</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body data-user="eyJjaGFydCI6eyJyZW5kZXJUbyI6IlByb2dyZXNzIiwidHlwZSI6ImNvbHVtbiJ9LCJzZXJpZXMiOlt7Im5hbWUiOiJQcm9ncmVzcyIsImRhdGEiOlsxLDEsMCwwLDAsMCwwLDAsMCwwXX1dLCJ0aXRsZSI6eyJ0ZXh0IjoiUHJvZ3Jlc3MifSwieEF4aXMiOlt7InR5cGUiOiJsaW5lYXIiLCJjYXRlZ29yaWVzIjpbIlJlZ2lzdGVyZWQ8YnI+KDQuNi4xMykiLCJTZXNzaW9uIDE8YnI+KDEyLjcuMTUpIiwiU2Vzc2lvbiAyIiwiU2Vzc2lvbiAzIiwiU2Vzc2lvbiA0IiwiU2Vzc2lvbiA1IiwiU2Vzc2lvbiA2IiwiU2Vzc2lvbiA3IiwiU2Vzc2lvbiA4IiwiRmluaXNoZWQiXX1dLCJ5QXhpcyI6W3sidGl0bGUiOnsidGV4dCI6IlNlc3Npb24gU3RhcnRlZCJ9LCJtaW4iOjB9XX0=">

<div id="wrap">
    <div class="container">

        <div class="report"></div>

    </div>
</div>

<script>
    window.onload = function (event) {

        event.preventDefault();

        $(".report").append("<div class='chart'><div id='Progress'><img src='staticMedia/img/loader.gif' /></div></div>");

        userData = $("body").data("user"); // get user report data
        var chart = new Highcharts.Chart(JSON.parse(atob(userData)));

        // destroys legend if only 1 series
        if (chart.series.length < 2) {
            chart.legend.destroy();
        }
    }
</script>

</body>
</html>
Arvind Maurya
  • 910
  • 12
  • 25
  • Have you tried to add console.log on error and success callbacks? You are setting html body with responseText on fail. Maybe you are getting an error response. – Beri Jan 30 '20 at 13:27
  • I can see in the browser's developer tools that the response from the server is definitely not an error: status code 200, and the content of the response is the HTML page I posted above. It's just that JQuery cannot process this HTML content for some reason, line number 154 from the error message I see in the console corresponds to the ```$("html").html(data);``` line in the script. – leo.demiurg Jan 30 '20 at 14:00
  • The problem has something to do with the inline script in the response HTML. When I remove it, there is not JQuery error. – leo.demiurg Jan 30 '20 at 14:13
  • The approach is unusual. Why not do a redirect or create a mvc controller that would handle this request? Secondly imported script will not execute on body swap. Try swappping only the body. – Beri Jan 30 '20 at 14:25
  • If, after receiving the initial POST request, I redirect the client instead of returning an HTML right away, the end result is going to be pretty much the same: the client will follow redirect silently, and the resulting GET request will acquire the same HTML content, after which the same success callback will be called - ```$("html").html(data);```, trying to process the same data. – leo.demiurg Jan 30 '20 at 14:50
  • As to the MVC controller to process the request - I'm not sure I follow. There is already an MVC controller implemented on the backend, and it does process the incoming POST request from the browser, the one which the sendXml() function sends. This controller then returns the view, which results in the client recieving an HTML content, which I'd like to see in the browser. – leo.demiurg Jan 30 '20 at 14:57
  • Found an answer here: https://stackoverflow.com/a/11984907/3182810. Replacing ```$("html").html(data);``` with ```document.open(); document.write(data); document.close();``` does the trick. – leo.demiurg Jan 30 '20 at 15:07
  • Does this answer your question? [Replace HTML page with contents retrieved via AJAX](https://stackoverflow.com/questions/483745/replace-html-page-with-contents-retrieved-via-ajax) – Peter O. Jun 02 '20 at 23:40

1 Answers1

0

Found an answer here: stackoverflow.com/a/11984907/3182810. Replacing

$("html").html(data);

in the form with

document.open(); 
document.write(data); 
document.close();

does the trick.