Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 22.11.2018, 16:28
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

https://imgur.com/a/zkoIzLh

<!DOCTYPE html>
<html>
<meta charset="UTF-8">

</html>
<script>

  fetch('/data.php').then(r => r.text()).then(r => console.log(r))

</script>


<?php
header('Content-Type: text/html; charset=windows-1251');
echo 'Привет русские буквы';


https://imgur.com/a/GxkNIHF
Ответить с цитированием
  #12 (permalink)  
Старый 22.11.2018, 16:31
Аспирант
Отправить личное сообщение для Svorg Посмотреть профиль Найти все сообщения от Svorg
 
Регистрация: 16.11.2018
Сообщений: 38

Надо всё на клиенте, без посредников. Пока вывернул так:
const fetchEx = (URL, Settings = {}) => {
  return new Promise((resolve, reject) => {
    const R = new XMLHttpRequest();
    R.open(Settings.method ? Settings.method : 'GET', URL);
    /*/ R.setRequestHeader('referer', Settings.referrer); /*/
    for (let key in Settings.headers) {
      R.setRequestHeader(key, Settings.headers[key]);
    };
    R.onload = () => resolve(R.response);
    R.onerror = () => reject(R.statusText);
    R.send(Settings.body);
  });
};

И работает. Теперь даже await *.text() делать не надо.
Ответить с цитированием
  #13 (permalink)  
Старый 21.11.2019, 21:56
Аспирант
Отправить личное сообщение для NeoN Посмотреть профиль Найти все сообщения от NeoN
 
Регистрация: 01.03.2013
Сообщений: 77

Добрый вечер, дамы и господа!
Так и не решился вопрос как нормально кириллицу через фетч получать без костылей? Тоже этот вопрос интересует.
Например, попытаемся взять контакты чатов из вк:
fetch('https://vk.com/al_im.php',{credentials: 'include', method: 'POST', headers: {
			'content-type':'application/x-www-form-urlencoded;charset=utf-8',
			'x-requested-with':'XMLHttpRequest',
			'origin':'https://vk.com'
		}, 
		body: '_smt=im%3A2&act=a_dialogs_preload&al=1&gid=0&im_v=2&rs='
    })
    .then(resp=>resp.json()).then(console.log)


вместо кириллицы будут вот эти символы в ответе:
"���������� ������� �� ������ ����������� �����",

видимо, все из-за того, что ответ приходит в таком виде:
content-type: application/json; charset=windows-1251

кто-нибудь знает как получать нормальный текст можно?

Последний раз редактировалось NeoN, 21.11.2019 в 22:25.
Ответить с цитированием
  #14 (permalink)  
Старый 21.11.2019, 22:56
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

Никак. Гении из комитета считают что весь интернет должен жить в utf8(небезосновательно, в целом) и таким образом насаждают свой видение. Как и в некоторых иных вопросах касательно fetch.
Потому fetch никто не использует, кроме как в примерчиках и он остаётся бесполезным мёртворожденным стандартом. Люди просто используют либы навроде axios.

"Правильным подходом" в вашем случае считается загрузка как буффера и декодирование в ручную с помощью TextDecoder.
__________________
29375, 35
Ответить с цитированием
  #15 (permalink)  
Старый 22.11.2019, 11:09
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

NeoN, вам нужно заменить ответ с проблемной кодировкой windows-1251 на другой ответ c правильной кодировкой utf-8...
async function windows1251ResponseToUTF8Response(response) {
	return new Response(new TextDecoder("windows-1251").decode(await response.arrayBuffer()));
}

fetch('https://vk.com/al_im.php', {
	credentials: 'include',
	method: 'POST',
	headers: {
		'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
		'x-requested-with': 'XMLHttpRequest',
		'origin': 'https://vk.com'
	},
	body: '_smt=im%3A2&act=a_dialogs_preload&al=1&gid=0&im_v=2&rs='
}).then(windows1251ResponseToUTF8Response).then(resp=>resp.json()).then(console.log)


Или преобразовать кодировку windows-1251 в utf-8...
function transformWindows1251ToUTF8(response) {
	const transformedBody = response.body
		.pipeThrough(new TextDecoderStream("windows-1251"))
		.pipeThrough(new TextEncoderStream("utf-8"));
	return new Response(transformedBody);
}

fetch('https://vk.com/al_im.php', {
	credentials: 'include',
	method: 'POST',
	headers: {
		'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
		'x-requested-with': 'XMLHttpRequest',
		'origin': 'https://vk.com'
	},
	body: '_smt=im%3A2&act=a_dialogs_preload&al=1&gid=0&im_v=2&rs='
}).then(transformWindows1251ToUTF8).then(resp=>resp.json()).then(console.log)



Сообщение от Aetae
Никак.
ОБМАН!!! Вы сами приводите ниже «правильный подход»!

Сообщение от Aetae
Гении из комитета считают что весь интернет должен жить в utf8(небезосновательно, в целом) и таким образом насаждают свой видение.
ОБМАН!!! Функция fetch возвращает асинхронно экземпляр класса Response, который вы можете обработать как угодно. Методы text и json у класса Response, которые декодируют ответ, действительно работают только с кодировкой utf-8, поскольку другие кодировки имеют определённые проблемы и их использование сокращается. Однако, например, метод arrayBuffer у класса Response не использует никакую кодировку, и представляет ответ при помощи ArrayBuffer. (Например, картинка или звук или бинарные данные, которые вы сами разбираете, например, преобразование потока в примере выше)

Сообщение от Aetae
Потому fetch никто не использует, кроме как в примерчиках и он остаётся бесполезным мёртворожденным стандартом.
ОБМАН!!! Fetch API используется в таких проектах — twitch.tv, imgur, GitHub и пр., а также частично — Instagram (для получения состояния авторизации), AliExpress и пр., а также в Service Worker-ах у YouTube, Google Maps и пр.

Сообщение от Aetae
Люди просто используют либы навроде axios.
ОБМАН!!! Например, Twitter использует для подгрузки сообщении jQuery.ajax (потому что им нужна поддержка старых браузеров), а для уведомлении — fetch (потому что Service Worker и Notification API всё равно в старых браузерах не работает, зачем тогда туда тянуть jQuery или axios).


axios – это обёртка над классом XMLHttpRequest в браузере и модулем http в node.js, использующая Promise.

Fetch API в совокупности со Streams API и Service Worker — это мощнейший инструмент для работы с передачей данных по сети, который может быть легко использован другими технологиями, например — Cache API, СSS Paint API и пр.
fetch – это о том как из запроса получить ответ, а не разобранный ответ в виде JSON, если вдруг получилось, что ответ похож на JSON.

Последний раз редактировалось Malleys, 22.11.2019 в 11:35.
Ответить с цитированием
  #16 (permalink)  
Старый 22.11.2019, 13:41
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

если все делать через жопу, через жопу и получится )
Ответить с цитированием
  #17 (permalink)  
Старый 22.11.2019, 21:25
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

Malleys, проблема тут в том, что сервер посылает конкретный стандартизированный заголовок Content-Type, и то что fetch его не учитывает потому что потому - это регрессия и ничто иное(ну или или просто плевок в лицо).
По остальному: естественно новый api приспособлен для работы с новыми api, но от этого он не становится лучше.

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

Последний раз редактировалось Aetae, 22.11.2019 в 21:35.
Ответить с цитированием
  #18 (permalink)  
Старый 22.11.2019, 22:07
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,126

На то есть причина.
fetch это JavaScript-овая фишка.
Она работает на движке JS а энкодер/декодер живет в браузерном окружении. Тут либо добавлять энкодер/декодер в движек JS и получить по два различных энкодера/декодера.
Либо добавить браузерное окружение в каждый выполняемый скрипт чтобы там был энкодер/декодер.
Либо придерживаться стандарта JS где кодировка для строковых типов строго определенна и не может быть другой.
Ответить с цитированием
  #19 (permalink)  
Старый 22.11.2019, 23:49
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Сообщение от MallSerg
fetch это JavaScript-овая фишка.
Она работает на движке JS
Здесь https://chromium.googlesource.com/v8/v8/ написано "V8 implements ECMAScript as specified in ECMA-262.", а ECMA-262 не специфицирует fetch.
Ответить с цитированием
  #20 (permalink)  
Старый 24.11.2019, 03:49
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,126

Ну да спецификация fetch живет в whatwg
Все крутится вокруг https://heycam.github.io/webidl/#idl-USVString и это не только fetch касается а для перекодировки предлагают использовать
https://encoding.spec.whatwg.org/#dom-textdecoder
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не отображаются данные. fetch phoenix200689 Библиотеки/Тулкиты/Фреймворки 0 17.12.2017 23:43
Авторизация в ВК с помощью fetch() caseyryan Общие вопросы Javascript 1 29.06.2017 10:38
После fetch на выходе Array, а не Collection _sky_ Backbone.js 2 06.02.2015 18:22
Выплывающее поле Макс3000 Элементы интерфейса 24 04.04.2012 19:29
Не проходит запрос в базу если в поле кириллица Sadist_dead Серверные языки и технологии 1 26.11.2011 17:12