我已经完成了什么
该应用程序有一个入口点main.js,它是我的react.js组件和依赖项的捆绑版本,因此我的index.html通常如下所示:
<body>
<script type="text/javascript" src="/static/bundles/main-3997ad3476694c3c91cf.js"></script>
</body>
我想做什么
考虑到我的应用程序是单页应用程序,我该如何处理?我不想重新发明轮子也不想复制我的代码。我必须编写什么样的node.js服务器才能实现这种自动服务器端呈现?有没有办法直接在Django中提供服务器端渲染(通过一些工具读取和解释客户端显示的页面的最终结果并返回此原始html?)
答案 0 :(得分:3)
您现在可能已经解决了问题,但我想分享我的解决方案。
我有一个非常相似的设置,到目前为止看起来效果很好。我基本上有一个django w / DRF后端api和同构React / Flux javascript应用程序。我还在python后端服务器旁边运行一个节点服务器,它只作为一个模板呈现&#39;服务。实质上,替换django render
函数。
所以我只需用一个特殊的View
替换django IsoView
,它通过http调用节点服务器并返回渲染的html。
from rest_framework.renderers import JSONRenderer
import requests
class IsoView(View):
def user_json(self):
if self.request.user.is_anonymous():
return {'anonymous': True}
else:
return UserSerializer(self.request.user, context={'request': self.request}).data
@classmethod
def render(cls, request, template, data):
req_data = JSONRenderer().render(data)
try:
headers = {'content-type': 'application/json'}
query_params = request.GET
resp = requests.post(_build_url(request.path), params=query_params, data=req_data, headers=headers, timeout=0.1)
reply = resp.json()
if resp.status_code == 302:
return redirect(reply.get('redirect'))
if 'error' in reply:
raise Exception("\n\nRemote traceback: {}".format(reply.get('traceback')))
except requests.exceptions.RequestException as err:
logger.warn('IsoView request exception: {}'.format(err))
reply = {}
return render(request, template, {
'react': reply.get('result'),
'data': data
})
并像这样使用它:
class HomePage(IsoView):
def get(self, request, *args, **kwargs):
return self.render(request, 'app.html', {
'user': json_data...
})
这也假设一个django模板使用类似这样的东西
<html>
<head>
<script>
window.data = {{ data|json }};
</script>
</head>
<body>{{ react|safe }}</body>
</html>
这样做是为了呈现从body标签中的节点返回的html,还会转储在window.data
对象中的客户端上引导应用程序所需的json数据。
这是系统的一个非常简化的版本,但它应该可以工作。你应该小心window.data
位上的XSS攻击,所以一定要逃避所有的json数据,但除此之外,你应该都很好。
然后,节点模板服务器看起来非常类似于您可以找到的任何服务器端反应教程。只是一个简单的快递应用程序。
或者,如果您渲染完整的... in节点并将其作为字符串返回,则根本不需要使用django模板。
希望有所帮助。