同构 JS - 仅限 httpRequest 客户端

Posted

技术标签:

【中文标题】同构 JS - 仅限 httpRequest 客户端【英文标题】:Isomorphic JS - httpRequest client side only 【发布时间】:2015-09-28 01:25:43 【问题描述】:

关于同构通量应用中存储数据填充的问题。 (我正在使用 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
    

有更好的想法吗?提前致谢。

【问题讨论】:

请添加更多信息!例如:代码示例、与问题相关的特定错误 添加了代码 sn-p 和更多详细信息 - 如果还有其他内容请告诉我 为什么不使用获取数据的请求,而不是在后端模拟 AJAX? AJAX 的全部意义在于您不想在前端重新加载页面。因为您正在进行后端渲染,只需向资源发送一个 get/post 请求,相应地解析您的数据并在发送给客户端之前渲染它。 是的。问题是我想同时渲染“后端”和“前端”数据,因此用户第一次点击页面时,它将被渲染为 BE,然后后续数据加载将来自客户端(稍微简化但足够近)。客户端渲染可以通过客户端的 GET 请求完成,SS 渲染可以通过内部 api 调用完成,问题是当 react store 在服务器端运行时,它会尝试进行 http 调用将无法做到(根据下面的 iSchluff 的回答,不添加某种支持。 【参考方案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 page

但是,如果您使用的不是直接基于 XMLHttpRequest 或显式节点感知(如 superagent)的任何东西,您可能需要对库函数本身进行填充。

在这个 sn-p 上要做的其他工作是实现错误和不同的内容类型。

【讨论】:

所以有这个模仿节点npmjs.com/package/xmlhttprequest上的xmlhttprequest,可以有条件地加载。 有任何以这种方式“填充”请求的示例吗?

以上是关于同构 JS - 仅限 httpRequest 客户端的主要内容,如果未能解决你的问题,请参考以下文章

第1057期服务端与客户端同构 —— Vue.js 应用框架 Nuxt.js

React.js同构实践

js httprequest 啥意思

仅限客户端的 Nuxt 3 D3 插件

如何使用 Dropzone.js 进行分块文件上传(仅限 PHP)?

没有通量的同构 react.js