WKWebView - Не удалось загрузить ресурс: нулевой источник не разрешен Access-Control-Allow-Origin

Я пытаюсь прочитать мой локальный файл JSON на IOS WKWebview. Однако Не удалось загрузить ресурс: Исходное значение null не разрешено Access-Control-Allow-Origin.

Я использую UIWebview раньше, и он работает нормально. Однако, когда я перехожу на WKWebview, эта ошибка происходит.

 $.ajax({
           type: 'GET',
            url: 'json_app/country_state_json.json?callback=?',
            async: false,
            jsonpCallback: 'jsonCallback',
            contentType: 'application/json',
            dataType: 'jsonp',
            success: function(json) 
            {},
            error: function(e) {}
        });

Пожалуйста помогите.

2 ответа

К сожалению, на данный момент WKWebView не обрабатывает асинхронную загрузку файлов JavaScript с использованием протокола "file://" [ 1] [ 2]. Он работает, когда файлы загружаются из DOM, просто не используя aget или jQuery.get (который просто абстрагируется как ajax).

Вот хак, которым я одновременно горжусь и не горжусь:

У меня есть приложение, которое должно загрузить объект JSON на основе некоторой динамической информации, а затем обработать его для отображения веб-содержимого. Первоначально я пытался, чтобы JavaScript получал файл JSON динамически:

Старый HTML:

<html>
  <head>
    <script type="text/javascript" src="makeContent.js"></script>
  </head>
  <body></body>
</html>

Старый JSON:

{
    "myData": true,
    ...
}

Старый JavaScript:

$.get("data.json", function (data) {
  // Process the data and generate the content
}, "json");

С этим я столкнулся с той же проблемой, что и вы. WKWebView не будет загружать файл data.json.

Мой хак состоял в том, чтобы включить контент JSON в качестве другого объекта JavaScript, который включен в DOM. Новый скрипт JavaScript просто назначает данные JSON в виде строки в глобальную переменную. Обратите внимание, что эта строка должна быть одной строкой, так как JavaScript не поддерживает многострочные строки. Затем этот новый скрипт динамически вставляется в DOM при загрузке WKWebView:

Файл данных JavaScript (заменяет файл JSON):

var data = '{ "myData": true, ... }';

Swift:

let jsonInsertion = "var node = document.createElement('script');" +
                    "node.setAttribute('src', 'data.js');" +
                    "node.setAttribute('type', 'text/javascript');" +
                    "var head = document.getElementsByTagName('head')[0];" +
                    "head.insertBefore(node, head.childNodes[0]);"
webView?.evaluateJavaScript(jsonInsertion, completionHandler:  { (_, error) in
    print(error)
})

Полученный HTML:

<html>
  <head>
    <script type="text/javascript" src="data.js"></script>
    <script type="text/javascript" src="makeContent.js"></script>
  </head>
  <body></body>
</html>

Теперь ваш JavaScript должен иметь возможность доступа к данным как глобальной переменной и преобразовывать их с помощью JSON.parse(data). Вам может понадобиться добавить некоторый код синхронизации, чтобы ваш скрипт запускался после того, как приложение вставит скрипт данных.

Опять же, это взлом, но это работает для меня. Надеюсь, это может быть полезно для вас, пока Apple не разрешит протокол "file://".

Могу поспорить, что вам нужно предоставить полный URL-адрес в запросе, а не относительный. Как насчет использования:

url: document.URL + "/json_app/country_state_json.json?callback=",

(Я снял конечный ? - это не правильно и приводит к неправильному URL)

Другие вопросы по тегам