Текстура загружена неправильно Три js chrome [дубликат]

Если вы не используете jQuery в своем коде, этот ответ для вас

Ваш код должен быть чем-то вроде этого:

function foo() {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
    return httpRequest.responseText;
}

var result = foo(); // always ends up being 'undefined'

Феликс Клинг отлично справился с написанием ответа для людей, использующих jQuery для AJAX, я решил предоставить альтернативу для людей, которые этого не делают.

( Примечание. используя новый API fetch, угловые или обещания, я добавил еще один ответ ниже )


То, с чем вы столкнулись

Это краткое резюме «Объяснение проблемы» из другого ответа, если вы не уверены, прочитав это, прочитайте это.

A в AJAX означает асинхронность. Это означает, что отправка запроса (или, скорее, получение ответа) вынимается из обычного потока выполнения. В вашем примере .send немедленно возвращается, а следующий оператор return result; выполняется до того, как функция, которую вы передали, когда был вызван обратный вызов success.

Это означает когда вы возвращаетесь, слушатель, который вы определили, еще не выполнил, что означает, что возвращаемое вами значение не было определено.

Вот простая аналогия

function getFive(){ 
    var a;
    setTimeout(function(){
         a=5;
    },10);
    return a;
}

(Fiddle)

Возвращаемое значение a - undefined так как часть a=5 еще не выполнена. AJAX действует так, вы возвращаете значение до того, как сервер получил возможность сообщить вашему браузеру, что это за значение.

Одним из возможных решений этой проблемы является код повторно активно , сообщая вашей программе, что делать, когда расчет завершен.

function onComplete(a){ // When the code completes, do this
    alert(a);
}

function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);
}

Это называется CPS . В основном, мы передаем getFive действие, которое необходимо выполнить, когда оно завершается, мы сообщаем нашему кодексу, как реагировать, когда событие завершается (например, наш вызов AJAX или в этом случае время ожидания).

Использование будет:

getFive(onComplete);

Который должен предупредить «5» на экране. (Fiddle) .

Возможные решения

Существуют два способа решения этой проблемы:

  1. Сделать AJAX синхронный вызов (позволяет называть его SJAX).
  2. Реструктурируйте свой код для правильной работы с обратными вызовами.

1. Синхронный AJAX - Не делайте этого !!

Что касается синхронного AJAX, не делайте этого! Ответ Феликса вызывает некоторые веские аргументы в пользу того, почему это плохая идея. Подводя итог, он заморозит браузер пользователя, пока сервер не вернет ответ и не создаст очень плохой пользовательский интерфейс. Вот еще краткое резюме из MDN о том, почему:

XMLHttpRequest поддерживает как синхронную, так и асинхронную связь. В общем, однако, асинхронные запросы должны быть предпочтительнее синхронных запросов по причинам производительности.

Короче говоря, синхронные запросы блокируют выполнение кода ... ... это может вызвать серьезные проблемы ...

Если вы имеете , вы можете передать флаг: Вот как это сделать:

var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {// That's HTTP for 'ok'
  console.log(request.responseText);
}

2. Код реструктуризации

Пусть ваша функция принимает обратный вызов. В примере код foo может быть сделан для принятия обратного вызова. Мы сообщим нашему кодексу, как отреагировали , когда foo завершает работу.

Итак:

var result = foo();
// code that depends on `result` goes here

Становится:

foo(function(result) {
    // code that depends on `result`
});

Здесь мы передали анонимную функцию, но мы могли бы так же легко передать ссылку на существующую , чтобы он выглядел следующим образом:

function myHandler(result) {
    // code that depends on `result`
}
foo(myHandler);

Для получения дополнительной информации о том, как выполняется этот вид обратного вызова, проверьте ответ Felix.

Теперь давайте определим сам foo, чтобы действовать соответственно

function foo(callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onload = function(){ // when the request is loaded
       callback(httpRequest.responseText);// we're calling our method
    };
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
}

(скрипка)

Теперь мы сделали нашу функцию foo принять действие, которое будет выполняться, когда AJAX завершится успешно, мы можем продолжить это, проверив, не является ли статус ответа не 200 и действует соответственно (создайте обработчик сбоя и т. д.). Эффективное решение нашей проблемы.

Если вам все еще трудно понять это , прочитайте руководство по началу работы AJAX в MDN.

660
задан corazza 2 December 2014 в 13:33
поделиться

22 ответа

656
ответ дан Andreas Wong 24 August 2018 в 21:30
поделиться
0
ответ дан Alex Gray 24 August 2018 в 21:30
поделиться
6
ответ дан BlackBeard 24 August 2018 в 21:30
поделиться
10
ответ дан bryc 24 August 2018 в 21:30
поделиться
11
ответ дан CommonsWare 24 August 2018 в 21:30
поделиться

Я получал эту точную ошибку при загрузке HTML-файла в браузере, который использовал json-файл из локального каталога. В моем случае я смог решить это, создав простой сервер узлов, который позволил статическому контенту сервера. Я оставил код для этого в этом другом ответе .

141
ответ дан Community 24 August 2018 в 21:30
поделиться

Подходим к этому сегодня.

Я написал код, который выглядит так:

app.controller('ctrlr', function($scope, $http){
    $http.get('localhost:3000').success(function(data) {
        $scope.stuff = data;
    });
});

... но он должен был выглядеть так:

app.controller('ctrlr', function($scope, $http){
    $http.get('http://localhost:3000').success(function(data) {
        $scope.stuff = data;
    });
});

Единственное различие заключалось в отсутствии http:// во втором фрагменте кода.

Просто хотелось поместить это там, если есть другие, имеющие аналогичную проблему.

51
ответ дан corazza 24 August 2018 в 21:30
поделиться
2
ответ дан Deniss M. 24 August 2018 в 21:30
поделиться
1
ответ дан Enayat Rajabi 24 August 2018 в 21:30
поделиться
0
ответ дан Fred Ondieki 24 August 2018 в 21:30
поделиться
0
ответ дан mgilberties 24 August 2018 в 21:30
поделиться
0
ответ дан Naga Sai A 24 August 2018 в 21:30
поделиться
-1
ответ дан Ngô Đức Tuấn 24 August 2018 в 21:30
поделиться
489
ответ дан Scott Stensland 24 August 2018 в 21:30
поделиться
0
ответ дан sujithklr93 24 August 2018 в 21:30
поделиться
25
ответ дан vaxquis 24 August 2018 в 21:30
поделиться
6
ответ дан Yash P Shah 24 August 2018 в 21:30
поделиться
0
ответ дан YUIOP QWERT 24 August 2018 в 21:30
поделиться

Я подозреваю, что это уже упоминалось в некоторых ответах, но я немного изменю это, чтобы получить полный рабочий ответ (проще найти и использовать).

  1. Перейти к: https://nodejs.org/en/download/. Установите nodejs.
  2. Установите http-сервер, запустив команду из командной строки npm install -g http-server.
  3. Перейдите в рабочий каталог, где index.html / yoursome.html находится.
  4. Запустите свой http-сервер, выполнив команду http-server -c-1

Откройте веб-браузер до http://localhost:8080 или http://localhost:8080/yoursome.html - в зависимости от вашего имени файла html.

0
ответ дан TarmoPikaro 8 October 2018 в 06:28
поделиться

В Chrome вы можете использовать этот флаг:

--allow-file-access-from-files

Подробнее здесь.

143
ответ дан Community 8 October 2018 в 06:28
поделиться
  • 1
    Это не работает для кофе-скриптов. – Blairg23 14 October 2014 в 06:03
  • 2
    @ Blairg23, имейте в виду, что это решение требует перезапуска всех экземпляров Chrome.exe для его работы – Alex Klaus 16 June 2015 в 23:41
  • 3
    Пожалуйста, объясните, как использовать его в хроме. – Rishabh Agrahari 28 August 2017 в 08:12
  • 4
    @Priya Не стоит этого делать – Suraj Jain 17 December 2017 в 07:12
  • 5
    Я бы предложил использовать Chromium только для локальной отладки (начиная с флага --allow-file-access-from-files). Это означает использование Chrome для обычного просмотра веб-страниц и использование Chromium в качестве приложения по умолчанию для HTML-файла. – Alan Zhiliang Feng 14 May 2018 в 11:23

Самый быстрый способ для меня: для пользователей Windows, которые запускают ваш файл в проблеме Firefox, или если вы хотите использовать хром для меня самым простым способом, это установить Python 3, затем из командной строки запустить команду python -m http.server, затем перейти к http: // localhost: 8000 / , затем перейдите к своим файлам

python -m http.server
0
ответ дан Rezzag Ridha 8 October 2018 в 06:28
поделиться
0
ответ дан KARTHIKEYAN.A 6 November 2018 в 21:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: