1

I have a Java application that as part of it's output creates an html report ,then opens the html reports in users browser. On Firefox and Google Chrome this works but on Safari it opens the report as if Javascript was not enabled, even though it is. However if you reopen the report by clicking on a link from another webpage (which lists all reports) then it opens fine in Safari.

What do I need to do to trigger Safari to open the report with Javascript enabled.

Console shows some errors, but I dont understand them

enter image description here

This is related issue https://apple.stackexchange.com/questions/361245/safari-kcferrordomaincfnetwork-error-1-on-local-html-files but doesn't provide a satisafactory answer.

Actually the answer here https://apple.stackexchange.com/questions/366448/safari-giving-kcferrordomaincfnetwork-error-303-when-visiting-a-site about removing my site from Preferecnes:Privacy works but that is no good because the problem occurs on new computer after running the program only a few times so would have to continually do it.

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351

2 Answers2

1

You open the file locally. Browsers usually restrict local file processing for security reasons. You must "Disable local file restrictions" in Safari in the "Developer" menu for making this possible. I am not sure, but it might be necessary to do this each time Safari opens such a file via your application. Embedding all external resources might also help, but I am not sure.

Opening the remote URL should always work. So this would be the best option. As an alternative you could serve the file to the browser via an embedded HTTP server in your application.

chromanoid
  • 545
  • 3
  • 14
  • 'Browsers usually restrict local file processing for security reasons', why is a local file more insecure than a remote file, problem only occurs on Safari, okay on Firefox and Chrome – Paul Taylor Feb 11 '21 at 07:41
  • Also a detail I think yo have missed is that if open the page from another local webpage then there is no problem. – Paul Taylor Feb 11 '21 at 07:42
  • Yeah, since I do not use Safari this was more a guessing game. Sorry! I think this blog post describes your problem: https://eclecticlight.co/2018/10/18/safari-12-0-cant-open-a-local-home-page/ My proposed solutions that do not depend on the browser still stand. – chromanoid Feb 11 '21 at 18:01
  • Regarding external resources in local resources, there usually should be a security policy in place: https://stackoverflow.com/questions/20748630/load-local-javascript-file-in-chrome-for-testing – chromanoid Feb 11 '21 at 18:07
  • 'Opening the remote URL should always work', so is there a remote url version of the local file url that i can use ? – Paul Taylor Feb 16 '21 at 13:13
  • No, I thought "another webpage (which lists all reports)" would be externally accessible through the web. In your case it seems to be another html document on your device - which is in my eyes not really a webpage. You would have to serve the documents via a local HTTP server to present them as a locally hosted "website" to the browser. Otherwise the browser will always handle those "webpages" as local documents and impose some restrictions. For example the browser can hardly decide which file accesses might be problematic and you cannot set cross origin policies in a normal way. – chromanoid Feb 17 '21 at 11:05
  • To give you an example of a security issue with local files presented in the browser: https://bugzilla.mozilla.org/show_bug.cgi?id=1500453 – chromanoid Feb 17 '21 at 11:21
  • BTW even when serving the file locally via localhost there are usually some restrictions imposed by browsers. – chromanoid Feb 17 '21 at 11:29
1

Edit: i just saw the previous answer proposed the same workaround, but i think copy paste code is always delicious. As for your problem, i verified this is occuring on safari and nothing else, and for me this fix worked.

Edit 2: According to this answer, it is a bug in Safari that it works when you open it via hyperlink. Without changing the developer settings in every users browser, it won't be working except on a local server. I'm sorry but it seems there is no other in-code workaround except what i already provided.

If you want to open with scripts at any cost, you can to the following workaround:

  • Write a minimalistic server socket (or copy paste my code):
    Index.java:
package index;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Index extends Base {
    public byte[] buildResponseBody(String resource) {
        try {
            System.out.println(resource);
            if(resource.contains("?"))  return "<!DOCTYPE HTML><html><h1>Error 404: Page not found</h1></html>".getBytes(StandardCharsets.US_ASCII);
            return Files.readAllBytes(Paths.get(resource));
        } catch (Exception e) {
            return "<!DOCTYPE HTML><html><h1>Error 404: Page not found</h1></html>".getBytes(StandardCharsets.US_ASCII);
        }
    }

    public static void main(String[] args) throws IOException {
        new Index().loop(80);
    }
}

Base.java:

package index;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class Base {
    public abstract byte[] buildResponseBody(String resource);

    String receiveRequest(BufferedReader reader) throws IOException {
        final Pattern getLinePattern = Pattern.compile("(?i)GET\\s+/(.*?)\\s+HTTP/1\\.[01]");
        String resource = null;
        try {
            for (String line = reader.readLine(); !line.isEmpty(); line = reader.readLine()) {
                Matcher matcher = getLinePattern.matcher(line);
                if (matcher.matches()) {
                    resource = matcher.group(1);
                }
            }
        } catch (NullPointerException e) {
            return null;
        }
        return resource;
}

    public void sendResponse(String resource, OutputStream output, PrintWriter writer) throws IOException {
        byte[] responseBody = buildResponseBody(resource);
        if (responseBody == null) {
            writer.println("HTTP/1.0 404 Not found");
            responseBody = "Not found".getBytes();
        } else
            writer.println("HTTP/1.0 200 OK");
        writer.println("Server: " + getClass().getSimpleName());
        writer.println("Content-Length: " + responseBody.length);
        writer.println();
        writer.flush();
        output.write(responseBody);
    }

    public void loop(int port) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            while (true)
                try (Socket socket = serverSocket.accept();
                     InputStream input = socket.getInputStream();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                     OutputStream output = socket.getOutputStream();
                     PrintWriter writer = new PrintWriter(new OutputStreamWriter(output))) {
                    sendResponse(receiveRequest(reader), output, writer);
                }
        }
    }
}

This enables opening a page at 127.0.0.1:80. If you now make sure the document is accessable to your application, you can make it open a browser window at your localhost:80/file.html. Since it now runs over an actual website not just a file in safari, the scripts should theoretically be working. (At least mine are in this code) You might want to improve security and remove some bugs of this code. I hope i could help.

RAVN Mateus
  • 560
  • 3
  • 13