8

Co już robiłemReactJS server side rendering fo pojedyncza strona aplikacji

  • Mam frontend w całości zbudowany z React.JS.
  • Cała logika biznesowa jest obsługiwana przez Django i udostępniana przez Django REST Framework za pośrednictwem interfejsu API.
  • Jestem w stanie budować dla różnych środowisk mobilnych (Android i iOS przez Cordova)
  • Aplikacja internetowa jest dostępna poprzez mój projekt Django (taki sam, który eksponuje api), frontend jest podobny do tego samego kodu ReactJS w pakiecie przez pakiet internetowy.
  • App ma jeden punkt wejścia, main.js który jest dołączony wersja moich react.js komponentów i zależności, a więc moja index.html zazwyczaj wygląda następująco:

    <body> 
        <script type="text/javascript" src="/static/bundles/main-3997ad3476694c3c91cf.js"></script> 
    </body> 
    

Co chcę zrobić

  • Chcę zapewnić renderowania po stronie serwera z mojej aplikacji internetowej, aby pozwolić robotów internetowych poprawnie indeksów na moją aplikację internetową (ja nie szukam po stronie serwera renderowania ruchoma B uilds)

Jak mogę sobie z tym poradzić, biorąc pod uwagę fakt, że moja aplikacja jest aplikacją na jedną stronę? Nie chcę wymyślać koła, ani kopiować kodu. Jaki rodzaj serwera node.js muszę napisać, aby uzyskać automatyczne renderowanie po stronie serwera? Czy istnieje sposób dostarczenia renderowania po stronie serwera bezpośrednio w Django (za pomocą niektórych narzędzi do czytania i interpretowania końcowych wyników strony wyświetlanych po stronie klienta i zwracania tego surowego html?)

+0

Zwykle instalowałeś backend Node.js i używałeś React.renderToString. Ponieważ używasz Django, być może będziesz musiał użyć czegoś takiego https://github.com/markfinger/python-react –

+0

Już szukałem tego pakietu, ale nie mogę znaleźć sposobu, żeby to działało ... Nie radzę sobie z parametrami "POST", które nie są akceptowane przez serwer, i nie wiem, jak skonfigurować "reverse proxy", o którym mówi ... – Pcriulan

+0

Co z tą biblioteką? https://github.com/defrex/django-react Nie jestem zaznajomiony z Django niestety, aby dać rzeczywistą pomoc, ale myślę, że po prostu chcesz uzyskać dostęp do metody renderToString Reacta podczas części renderowania serwera na Django. Czy istnieje sposób na uruchamianie JS po stronie serwera w Django? –

Odpowiedz

2

Prawdopodobnie rozwiązałeś swój problem teraz, ale chciałem podzielić się moim rozwiązaniem.

Mam bardzo podobne ustawienia i mam coś, co do tej pory działa całkiem nieźle. Zasadniczo mam api api do aplikacji django w/DRF i do jaomowej aplikacji Isomorphic React/Flux. Uruchamiam także serwer węzłów obok serwera zaplecza Pythona, który działa tylko jako usługa "renderowania szablonu". W istocie, zastępując funkcję django render.

Po prostu zastępuję django View specjalnym IsoView, który wywołuje za pośrednictwem protokołu http do serwera węzłów i zwraca renderowany 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 
     }) 

i używać go tak:

class HomePage(IsoView): 

    def get(self, request, *args, **kwargs): 
     return self.render(request, 'app.html', { 
      'user': json_data... 
     }) 

ta zakłada również szablonu django, które używa coś takiego

<html> 
<head> 
    <script> 
     window.data = {{ data|json }}; 
    </script> 
</head> 
<body>{{ react|safe }}</body> 
</html> 

Co to robi to czyni html zwrócony z węzła w tag body, a także zrzuca dane json wymagane do ładowania aplikacji na kliencie w obiekcie window.data.

To naprawdę uproszczona wersja systemu, ale powinna działać. Powinieneś być ostrożny z atakami XSS na bit window.data, więc pamiętaj, aby uciec od wszystkich danych json, ale poza tym, powinieneś być dobry.

Następnie serwer szablonów węzłów wygląda bardzo podobnie do każdego z tutoriali dostępnych online, które można zareagować po stronie serwera. Prosta aplikacja ekspresowa.

Alternatywnie, nie musisz w ogóle kompliować się z szablonami django, jeśli renderujesz pełny węzeł w węźle i zwracasz go jako ciąg.

Nadzieję, że pomaga.