У меня есть текстовый файл в корне моего веб-приложения http: //localhost/foo.txt, и я хотел бы загрузить его в переменную в javascript .. в Groovy я бы сделал следующее:
def fileContents = 'http://localhost/foo.txt'.toURL().text;
println fileContents;
Как я могу получить аналогичный результат в javascript?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


XMLHttpRequest, то есть AJAX, без XML.
Точный способ, которым вы это сделаете, зависит от того, какую платформу JavaScript вы используете, но если мы не будем учитывать проблемы совместимости, ваш код будет выглядеть примерно так:
var client = new XMLHttpRequest();
client.open('GET', '/foo.txt');
client.onreadystatechange = function() {
alert(client.responseText);
}
client.send();Однако, как правило, XMLHttpRequest доступен не на всех платформах, поэтому налицо некоторая подделка. Еще раз, лучше всего использовать фреймворк AJAX, например jQuery.
Еще одно замечание: это будет работать, только если foo.txt находится в том же домене. Если он находится в другом домене, политики безопасности того же происхождения не позволят вам прочитать результат.
Было бы полезно добавить, что внутри onreadystatechange вы можете получить доступ к свойству readystate объекта XMLHttpRequest (в примере: client.readystate), чтобы узнать, каков статус, поскольку событие onreadystatechange возникает для загрузки, загрузки, .. .. поэтому вы должны дождаться client.readystate == 4 внутри onreadystatechange, прежде чем сможете использовать client.responseText.
@GameAlchemist: наткнулся на ваш отличный ответ. Я просто хотел отметить, что в большинстве браузеров readyState имеет верблюжий корпус, поэтому код должен быть примерно таким: if (client.readyState === 4){ }
Дополнительно вы можете сделать client.onloadend и просто получить полные данные
Ответ должен быть отредактирован, чтобы включить проверку значения свойства client.readyState. Я голосую против, пока это не так, люди не будут читать комментарии, чтобы обнаружить, что ответ верен только частично.
Получаю ошибку Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
Есть много решений. Это просто здорово.
@OneWorld JSONP можно использовать только для загрузки данных JSON, не так ли? Я думал, что его нельзя использовать для загрузки текста (foo.txt), чего хочет OP, или для загрузки, например. XML.
Если текст, который вы пытаетесь загрузить, является просто некоторой конфигурацией, необходимой для запуска вашего javascript ... рассмотрите возможность переформатирования вашей конфигурации в небольшой файл javascript, который устанавливает переменную javascript, и используйте <script src = 'myconfig.js'> </ script>, чтобы загрузить его.
Если ваш ввод был структурирован как XML, вы можете использовать функцию importXML. (Подробнее здесь, в quirksmode).
Если это не XML и нет эквивалентной функции для импорта простого текста, вы можете открыть его в скрытом iframe, а затем прочитать оттуда содержимое.
вот как я это сделал в jquery:
jQuery.get('http://localhost/foo.txt', function(data) {
alert(data);
});
который, похоже, не работает с обычными табличными текстовыми данными (docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests)
Обратите внимание, что это не работает, если вы тестируете его локально с помощью file://, то есть file:///example.com/foo.html. Firefox жалуется на синтаксическую ошибку и блокирует Chrome, поскольку считает это запросом Cross-Origin.
@pufferfish он будет работать с простыми данными, если вы укажете параметр dataType, см. api.jquery.com/jQuery.get/
@Akronix, если вы опустите часть http://..., потому что она находится в том же домене, она будет работать, например jQuery.get("foo.txt", ...).
@Akronix Есть простой способ протестировать его локально? Я продолжаю получать сообщения об ошибках при запросе на другой источник
Это сработало для меня, когда я добавил localhost: 9090 (адрес порта, который использует мой сервер).
@yvesonline Хорошо, jQuery.get("foo.txt", ...) решает проблему Cross-Origin, но приходит другая: ошибка not well-formed, и невозможно загрузить контент. Я не понимаю, почему это не работает и почему это работает ...
Следует иметь в виду, что Javascript работает на клиенте, а не на сервере. Вы действительно не можете «загрузить файл» с сервера в Javascript. Что происходит, так это то, что Javascript отправляет запрос на сервер, а сервер отправляет обратно содержимое запрошенного файла. Как Javascript получает содержимое? Для этого и предназначена функция обратного вызова. В случае Эдварда это
client.onreadystatechange = function() {
а в случае с данбом это
function(data) {
Эта функция вызывается всякий раз, когда приходят данные. Версия jQuery неявно использует Ajax, она просто упрощает кодирование, инкапсулируя этот код в библиотеке.
При работе с jQuery вместо использования jQuery.get, например.
jQuery.get("foo.txt", undefined, function(data) {
alert(data);
}, "html").done(function() {
alert("second success");
}).fail(function(jqXHR, textStatus) {
alert(textStatus);
}).always(function() {
alert("finished");
});
вы можете использовать .load, который дает вам гораздо более сжатую форму:
$("#myelement").load("foo.txt");
.load также дает возможность загружать частичные страницы, которые могут пригодиться, см. api.jquery.com/load/.
Если вам нужна только постоянная строка из текстового файла, вы можете включить ее как JavaScript:
// This becomes the content of your foo.txt file
let text = `
My test text goes here!
`;<script src = "foo.txt"></script>
<script>
console.info(text);
</script>Строка, загруженная из файла, становится доступной для JavaScript после загрузки. Символ `(обратная кавычка) начинается и заканчивается литерал шаблона, что позволяет использовать в текстовом блоке как символы", так и ".
Этот подход хорошо работает, когда вы пытаетесь загрузить файл локально, поскольку Chrome не разрешает использование AJAX для URL-адресов со схемой file://.
Это было бы действительно отличное решение. Но литерал шаблона не поддерживается в IE11, а переменная let будет вне области видимости внутри функционального блока, поэтому такая реализация чревата опасностями - будьте осторожны.
На данный момент даже Microsoft собирается отказаться от IE, и область действия можно упростить, сделав его функцией, которая возвращает строку вместо установки переменной с помощью let.
Это должно работать почти во всех браузерах:
var xhr=new XMLHttpRequest();
xhr.open("GET","https://12Me21.github.io/test.txt");
xhr.onload=function(){
console.info(xhr.responseText);
}
xhr.send();
Кроме того, есть новый API Fetch:
fetch("https://12Me21.github.io/test.txt")
.then( response => response.text() )
.then( text => console.info(text) )
fetch('http://localhost/foo.txt')
.then(response => response.text())
.then((data) => {
console.info(data)
})
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
Да, Fetch - это (недавний) стандарт, а не собственное расширение.
Сейчас 2019 год, и доставка - вещь прекрасная. Это путь для всех современных браузеров, включая Samsung Internet, который только что догнал ...
Компактный и рабочий код, Вик, спасибо. Можно ли было бы где-нибудь в вашем коде разместить response.ok (или эквивалент), чтобы добиться обработки ошибок? Я не очень разбираюсь в fetch, поэтому не знаю, где его установить.
Отличное решение. Это было очень просто даже для новичка. Сохраняется в переменной вместо console.info на последнем шаге, теперь можно использовать где угодно.
Внутри функции async вы можете выполнить const text = await fetch(url).then($ => $.text()), чтобы сгладить обратный вызов.
const response = await fetch('http://localhost/foo.txt');
const data = await response.text();
console.info(data);
Обратите внимание, что await может использоваться только в функции async. Более длинный пример мог бы быть
async function loadFileAndPrintToConsole(url) {
try {
const response = await fetch(url);
const data = await response.text();
console.info(data);
} catch (err) {
console.error(err);
}
}
loadFileAndPrintToConsole('https://threejsfundamentals.org/LICENSE');
Обходной путь для политики того же происхождения - использование JSONP, который также поддерживается jQuery (для клиентской части)