在同构反应应用程序中,是否有最简洁的方式在客户端和服务器端获取当前的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() 

这是“正确”还是“最佳实践”? 不知道,但它运作良好,易于遵循:)