Изоморфный JS - только на стороне клиента httpRequest

Вопрос о заполнении данных хранилища в изоморфных потоковых приложениях. (Я использую react, alt, iso и node, но теория применима и к другим примерам)

У меня есть "магазин" потока (http://alt.js.org/docs/stores/), которому нужно получить данные из API:

getState() {
   return {
       data : makeHttpRequest(url)
   }
}

и по мере того, как пользователь перемещается по SPA, дополнительные данные будут загружаться через HTTP-запросы.

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

react.renderToString() позволяет мне визуализировать приложение как html, и я могу заполнить данные, используя alt&iso, например:

storeData = { "MyStore" : {"key" : "value"}}; // set data for store
alt.bootstrap(JSON.stringify(storeData || {})); // seed store with data

var content = React.renderToString(React.createElement(myApp)); // render react app to html

Проблема в том, что я увижу ошибки при запуске на стороне сервера js, так как магазин захочет сделать http-запрос, который он не сможет сделать (поскольку xmlhttprequest не будет существовать в узле)

Какой лучший способ решить эту проблему?

Единственное решение, которое я могу придумать, это обернуть httprequest из магазина:

var ExecutionEnvironment = require('react/lib/ExecutionEnvironment');

    ...

    if (ExecutionEnvironment.canUseDOM) {
        // make http request
    } else {
        // do nothing
    }

Есть идеи получше? Заранее спасибо.


person theStonehill    schedule 09.07.2015    source источник
comment
Добавьте больше информации, пожалуйста! Например: образцы кода, конкретные ошибки, связанные с вопросом   -  person Bwaxxlo    schedule 09.07.2015
comment
добавлен фрагмент кода и более подробная информация - дайте мне знать, если есть что-то еще   -  person theStonehill    schedule 09.07.2015
comment
Почему бы не использовать запрос на получение данных вместо имитации AJAX в бэкэнде? Весь смысл AJAX в том, что вы не хотите перезагружать страницу во внешнем интерфейсе. Поскольку вы выполняете бэкэнд-рендеринг, просто отправьте запрос на получение/публикацию ресурсу, соответствующим образом проанализируйте свои данные и отобразите их перед отправкой клиенту.   -  person Bwaxxlo    schedule 09.07.2015
comment
Да. Проблема в том, что я хочу отображать данные как «задним», так и «передним» концом, поэтому в первый раз, когда пользователь попадает на страницу, она будет отображаться BE, а затем последующие загрузки данных будут поступать от клиента (слегка упрощенный, но достаточно близко). Рендеринг на стороне клиента может быть выполнен с помощью запроса GET от клиента, а рендеринг SS может быть выполнен с помощью внутреннего вызова API. не сможет сделать (без добавления какой-либо поддержки в соответствии с ответом iSchluff ниже.   -  person theStonehill    schedule 10.07.2015


Ответы (1)


Я бы порекомендовал подключиться к вашей библиотеке Ajax или XMLHttpRequest напрямую, если вы работаете на стороне сервера. Просто дополните его кодом, который предоставляет данные непосредственно из вашей базы данных или приложения.

Краткий пример:

var noop= function(){}

window.XMLHttpRequest= function(){
    console.log("xhr created", arguments);
    return {
        open: function(method, url){
            console.log("xhr open", method, url);
            // asynchronously respond
            setTimeout(function(){
                // pull this data from your database/application
                this.responseText= JSON.stringify({
                    foo: "bar"
                });
                this.status= 200;
                this.statusText= "Marvellous";
                if(this.onload){
                    this.onload();
                }
                // other libs may implement onreadystatechange
            }.bind(this), 1)
        },
        // receive data here
        send: function(data){
            console.log("xhr send", data);
        },
        close: noop,
        abort: noop,
        setRequestHeader: noop,
        overrideMimeType: noop,
        getAllResponseHeaders: noop,
        getResponseHeader: noop,
    };
}

$.ajax({
    method: "GET",
    url: "foo/bar",
    dataType: "json",
    success: function(data){
        console.log("ajax complete", data);
    },
    error: function(){
        console.log("something failed", arguments);
    }   
});

http://jsfiddle.net/qs8r8L4f/

Я сделал это за последние 5 минут, в основном используя XMLHTTPRequest mdn-страницу

Однако, если вы используете что-либо, не основанное непосредственно на XMLHttpRequest или явно осведомленное об узле (например, суперагент), вам, вероятно, потребуется проложить саму библиотечную функцию.

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

person iSchluff    schedule 09.07.2015
comment
Итак, это имитирует xmlhttprequest на узле https://www.npmjs.com/package/xmlhttprequest, который может быть условно загружен. - person theStonehill; 09.07.2015
comment
Какие-нибудь примеры "перемешивания" запроса таким образом? - person theStonehill; 09.07.2015