Firefox Fail - After using [removed] and update to

2019-08-30 17:55发布

问题:

Here is some HTML (Fiddle):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Test Write</title>
<script>
    function test() {
        if (window.location.hash == '#test') {
            alert('The hash is already set!');
        } else {
            document.open();
            document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\
<html>\
<head>\
<title>Hello There!</title>\
<script>\
    function test() {\
        window.location.hash="test";\
    }\
</'+'script>\
</head>\
<body>\
    <button onclick="test()">Test Hash Now</button>\
</body>\
</html>');
            document.close();
        }
    }
</script>
</head>
<body>
    <button onclick="test()">Click to write new page</button>
</body>
</html>

If you run this - then click "Click to write new page" - it will write a new HTML fragment onto the document. This time there is a button to "Test Hash Now" - when you click all it does is update the window.location.hash.

In FireFox the page tries to reload again unexpectedly. In all other browsers it works fine. In Fiddle you will see an error message {"error": "Please use POST request"} if you create a HTML file it will work better, you'll see the "Click to write new page" button appear again after clicking "Test Hash Now" which is (or should be) wrong.

Why is this happening?

My use case is simple - I have a bootstrap page that contains a javascript that fetches a bunch of data using AJAX. It then generates a large HTML string (including doctype/head/body/etc) and then it just needs to render that HTML string.

In this case I am using an inline HTML as a constant - but in the real case it is generating it using some logic. I am trying to simulate what the server will respond with and eliminate any server side requirements for the client.

I would just have a bunch of HTML and JS files zipped up into one file, and I could give that to anyone (developer or not) to run without any need for a server or database. Then they could see the page as if it were the real-deal. That's my goal. If I simply put the HTML into an existing element on the page (such as just manipulating the body of the current page) - it won't behave EXACTLY the same as if the entire document were generated. Plus I want the bootstrap HTML file to be really small (with just one javascript include at the top).

Everything seems to work - except Firefox is the only one that fails. It all works unless there is a script referenced inside the page that needs to write something to the window.location.hash - then it tries to reload the whole page... Uggg...

Any better way to accomplish this?

I tried to create an iframe and using the same document.open();document.write(html);document.close() - but the same exact issue happens.

回答1:

Try this code to push the hash state:

if (history.pushState) {
    history.pushState(null, null, '#test');
}
else {
    location.hash = '#test';
}

but I haven't tested it myself.

Added: Try naming your functions test1() and test2(). This won't fix it necessarily, but it may help to debug/discover what is happening.