在同构反应应用程序中,是否有最简洁的方式在客户端和服务器端获取当前的URL?
我正在开发一个基于这个 React Redux样板的应用程序。 在一个组件中,为了生成社交媒体的可共享URL,我需要获取当前组件的当前URL。 使用React Router,可以从dynamic生成的URL访问组件。 在客户端,我不会有任何问题通过JavaScript document
对象,但问题在于服务器端。
我想在Redux存储中提供保存在此config.js
文件中的Node.js环境数据,其中保存了主机名
// Node.js environment file config.js require('babel-polyfill'); const environment = { development: { isProduction: false }, production: { isProduction: true } }[process.env.NODE_ENV || 'development']; module.exports = Object.assign({ host: process.env.HOST || 'localhost', port: process.env.PORT, apiHost: process.env.APIHOST || 'localhost', apiPort: process.env.APIPORT }, environment);
并将React Router的location
对象设置为组件中的道具,获取path名并完全构造URL。
我所做的就是创build一个初始状态的简单reducer,以保持Node.jsconfiguration环境数据,并且只需要将默认操作包含在与其他应用程序reducer的combineReducers
函数中。
const initialState = { config: {} }; export default function config(state = initialState, action = {}) { switch (action.type) { default: return state; } }
然后,我在创build存储时将环境数据的Node.js对象注入到我的server.js
文件中,作为初始状态数据。
import config from './config'; ... const store = createStore(memoryHistory, client, {config}); ...
因此,我有可用的主机名,我可以在组件中通过Redux商店构build它的完整的URL客户端和服务器端。
但是,有没有更简单/最干净的方法? 恐怕我可能会过度使用它,或者为我的应用程序创build任何安全问题。
试图使用头盔服务器端时,我遇到了这个问题。 我将请求作为道具传递给我的主要<App>
组件,然后使用请求对象(服务器端)或窗口对象(客户端)。
App.js
render() { // Get full url from client or server let fullURL = '' if(typeof window !== 'undefined'){ fullURL = window.location.protocol + '//' + window.location.host + this.props.location.pathname }else if(this.props.serverRequest){ fullURL = this.props.serverRequest.headers.host + '/' + this.props.location.pathname } const urlTag = fullURL === '' ? null : <meta property="og:url" content={fullURL} /> const linkTag = fullURL === '' ? null : <link rel="canonical" href={fullURL} /> const helmet = this.props.siteInfo.site ? <Helmet> <title>{this.props.siteInfo.site.title}</title> <meta property="twitter:title" content={this.props.siteInfo.site.title} /> {urlTag} {linkTag} <meta property="og:type" content="website" /> </Helmet> : null return ( <div> {helmet} <Notices /> <div className="body"> <Header /> <Body /> </div> <Footer /> </div> ) }
server.js
const markup = renderToString( <Provider store={store}> <StaticRouter location={req.url} context={context}> <App serverRequest={req} /> </StaticRouter> </Provider> ) const helmet = Helmet.renderStatic()
这是“正确”还是“最佳实践”? 不知道,但它运作良好,易于遵循:)
- 使用grunt-contrib-connect和grunt-connect-rewrite删除文件扩展名
- 如何让Sinon的fakeServer在Mocha和Node中响应jQuery.ajax调用?
- 实时协作丰富的文本编辑
- 重新呈现一个网页
- Javascript模块:原型与导出
- 获取__dirname指向文件夹path,而不是实际连接的文件夹path
- 如何隐藏用Electron(asar文件)构build的nodeJS解决scheme的源代码?
- 你仍然可以使用PHP作为后端angularjs2没有nodejs实时应用程序?
- 未处理的Promise拒绝警告:TypeError:第一个参数必须是string或缓冲区