Używam S3 do hostowania aplikacji javascript, która będzie używać pushStates HTML5. Problem polega na tym, że jeśli użytkownik doda zakładkę do dowolnego adresu URL, nie rozwiąże niczego. To, czego potrzebuję, to możliwość przyjmowania wszystkich żądań adresu URL i podawania root index.html w moim segmencie S3, zamiast tylko pełnego przekierowania. Wtedy moja aplikacja javascript mogłaby przeanalizować adres URL i wyświetlić odpowiednią stronę.
Czy jest jakiś sposób, aby powiedzieć S3, aby wyświetlał plik index.html dla wszystkich żądań URL zamiast przekierowywać? Byłoby to podobne do konfigurowania apache do obsługi wszystkich przychodzących żądań przez serwowanie pojedynczego pliku index.html, jak w tym przykładzie: https://stackoverflow.com/a/10647521/1762614 . Naprawdę chciałbym uniknąć uruchamiania serwera WWW tylko do obsługi tych tras. Robienie wszystkiego z S3 jest bardzo atrakcyjne.
Odpowiedzi:
Bardzo łatwo go rozwiązać bez włamań do adresów URL, z pomocą CloudFront.
źródło
Sposób, w jaki udało mi się to uruchomić, jest następujący:
W sekcji Edytuj reguły przekierowania konsoli S3 dla swojej domeny dodaj następujące reguły:
Spowoduje to przekierowanie wszystkich ścieżek, w wyniku których 404 nie zostanie znalezione w domenie głównej za pomocą wersji mieszania ścieżki. Więc http://twojadomena.com.com/posts przekieruje na http://twojadomena.com.com/#!/posts pod warunkiem, że nie ma pliku w / posts.
Aby jednak użyć pushStates HTML5, musimy przyjąć to żądanie i ręcznie ustalić poprawne pushState na podstawie ścieżki hash-bang. Dodaj to na górze pliku index.html:
Pobiera to skrót i przekształca go w pushState HTML5. Od tego momentu możesz używać pushStates, aby mieć w aplikacji ścieżki nie-hash-bang.
źródło
<script language="javascript"> if (typeof(window.history.pushState) == 'function') { window.history.pushState(null, "Site Name", window.location.hash.substring(2)); } else { window.location.hash = window.location.hash.substring(2); } </script>
react-router
z tym rozwiązaniem, używając HTMLState pushStates i<ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
Jest kilka problemów z podejściem opartym na S3 / Redirect wspomnianym przez innych.
Rozwiązaniem jest:
Skonfiguruj reguły stron błędów dla instancji Cloudfront. W regułach błędów określ:
Kod odpowiedzi HTTP: 200
Skonfiguruj instancję EC2 i skonfiguruj serwer nginx.
Mogę pomóc w bardziej szczegółowych szczegółach dotyczących konfiguracji nginx, po prostu zostaw notatkę. Nauczyłem się tego na własnej skórze.
Po zaktualizowaniu dystrybucji frontowej w chmurze. Unieważnij raz pamięć podręczną działającą w chmurze, aby być w nieskazitelnym trybie. Naciśnij adres URL w przeglądarce i wszystko powinno być dobre.
źródło
If-Modified-Since
wysyłane jest żądanie GET do źródła) - może być użytecznym rozwiązaniem dla osób, które nie chcą skonfigurować serwer jak w kroku 5.Jest to styczne, ale oto wskazówka dla tych, którzy używają biblioteki React Router Rackta z historią przeglądarki (HTML5), którzy chcą hostować na S3.
Załóżmy, że użytkownik odwiedza
/foo/bear
statyczną witrynę hostowaną przez S3. Biorąc pod uwagę wcześniejszą sugestię Davida , reguły przekierowania wyślą je na adres . Jeśli twoja aplikacja jest zbudowana przy użyciu historii przeglądarki, nie przyniesie to wiele dobrego. Jednak aplikacja jest ładowana w tym momencie i może teraz manipulować historią./#/foo/bear
Uwzględniając historię Rackta w naszym projekcie (zobacz także Korzystanie z historii niestandardowych z projektu React Router), możesz dodać detektora, który jest świadomy ścieżek historii skrótów i odpowiednio zastąpić ścieżkę, jak pokazano w tym przykładzie:
Przypomnę:
/foo/bear
do/#/foo/bear
.#/foo/bear
zapis historii.Link
tagi będą działać zgodnie z oczekiwaniami, podobnie jak wszystkie inne funkcje historii przeglądarki. Jedynym minusem, jaki zauważyłem, jest przekierowanie śródmiąższowe, które występuje na pierwsze żądanie.Inspiracją było rozwiązanie dla AngularJS i podejrzewam, że można je łatwo dostosować do dowolnego zastosowania.
źródło
browserHistory.listen
Widzę 4 rozwiązania tego problemu. Pierwsze 3 zostały już uwzględnione w odpowiedziach, a ostatni jest moim wkładem.
Ustaw dokument błędu na index.html.
Problem : treść odpowiedzi będzie poprawna, ale kod stanu to 404, co boli SEO.
Ustaw reguły przekierowania.
Problem : adres URL jest zanieczyszczony,
#!
a strona ładuje się po załadowaniu.Skonfiguruj CloudFront.
Problem : wszystkie strony zwrócą 404 od początku, więc musisz wybrać, jeśli nie będziesz niczego buforować (sugerowane TTL 0) lub jeśli będziesz buforować i będziesz mieć problemy z aktualizacją strony.
Wstępnie wyrenderuj wszystkie strony.
Problem : dodatkowa praca w celu wstępnego renderowania stron, szczególnie gdy strony często się zmieniają. Na przykład witryna z wiadomościami.
Moją propozycją jest skorzystanie z opcji 4. Jeśli wstępnie wyrenderujesz wszystkie strony, nie będzie 404 błędów dla oczekiwanych stron. Strona ładuje się dobrze, a środowisko przejmuje kontrolę i działa normalnie jako SPA. Możesz także ustawić dokument błędu, aby wyświetlał ogólną stronę error.html oraz regułę przekierowania, aby przekierowywać błędy 404 na stronę 404.html (bez hashbanga).
Jeśli chodzi o 403 zabronione błędy, w ogóle ich nie dopuszczam. W mojej aplikacji uważam, że wszystkie pliki w segmencie hosta są publiczne i ustawiam to za pomocą opcji Wszyscy z uprawnieniem do odczytu . Jeśli Twoja witryna ma prywatne strony, pozwolenie użytkownikowi na zobaczenie układu HTML nie powinno stanowić problemu. To, czego potrzebujesz do ochrony, to dane, a odbywa się to w wewnętrznej bazie danych.
Ponadto, jeśli masz prywatne zasoby, takie jak zdjęcia użytkowników, możesz zapisać je w innym segmencie. Ponieważ zasoby prywatne wymagają takiej samej opieki jak dane i nie można ich porównywać z plikami zasobów używanymi do hostowania aplikacji.
źródło
Zetknąłem się dzisiaj z tym samym problemem, ale rozwiązanie @ Mark-Nutter było niekompletne, aby usunąć hashbang z mojej aplikacji angularjs.
W rzeczywistości musisz przejść do Edycji uprawnień , kliknąć Dodaj więcej uprawnień, a następnie dodać odpowiednią listę w wiadrze do wszystkich. Przy tej konfiguracji AWS S3 będzie mógł teraz zwrócić błąd 404, a następnie reguła przekierowania odpowiednio złapie sprawę.
Takie jak to :
Następnie możesz przejść do Edycji reguł przekierowania i dodać tę regułę:
Tutaj możesz zastąpić nazwę hosta subdomain.domain.fr swoją domeną i KeyPrefix #! / Jeśli nie używasz metody hashbang do celów SEO.
Oczywiście wszystko to zadziała tylko wtedy, gdy masz już konfigurację trybu html5 w aplikacji kątowej.
źródło
Najłatwiejszym rozwiązaniem, aby aplikacja Angular 2+ była obsługiwana z Amazon S3 i bezpośrednich adresów URL, jest określenie index.html zarówno jako dokumentów indeksu, jak i błędów w konfiguracji segmentu S3.
źródło
body
odpowiedzi. Kod stanu to 404 i zaszkodzi SEO.body
przypadku, gdy masz w nim zaimportowane skrypty,head
nie będą one działać, gdy bezpośrednio trafisz na którąkolwiek z tras podrzędnych na swojej stronieponieważ problem nadal istnieje, pomyślałem, że wprowadzę inne rozwiązanie. Mój przypadek polegał na tym, że chciałem automatycznie wdrożyć wszystkie żądania ściągnięcia do s3 w celu przetestowania przed scaleniem, aby były dostępne na [mojadomena] / pull-request / [pr number] /
(np. Www.example.com/pull-requests/822/ )
Zgodnie z moją najlepszą wiedzą, scenariusze inne niż reguły s3 pozwoliłyby na posiadanie wielu projektów w jednym segmencie przy użyciu routingu HTML5, więc chociaż powyższa sugestia nad większością głosów działa dla projektu w folderze głównym, nie dotyczy wielu projektów we własnych podfolderach.
Wskazałem więc moją domenę na mój serwer, na którym wykonałem zadanie po konfiguracji nginx
próbuje pobrać plik, a jeśli nie zostanie znaleziony, zakłada, że jest to trasa HTML5 i próbuje tego. Jeśli masz stronę kątową 404 dla nieodnalezionych tras, nigdy nie dostaniesz się do @not_found i otrzymasz zwrotną stronę 404 zamiast nieodnalezionych plików, co można naprawić za pomocą niektórych, jeśli reguła w @get_routes lub coś takiego.
Muszę powiedzieć, że nie czuję się zbyt komfortowo w zakresie konfiguracji nginx i używania wyrażeń regularnych w tej kwestii, dostałem to z pewną próbą i błędem, więc chociaż działa, jestem pewien, że jest miejsce na ulepszenia i proszę podziel się swoimi przemyśleniami .
Uwaga : usuń reguły przekierowania s3, jeśli masz je w konfiguracji S3.
a btw działa w Safari
źródło
Szukał tego samego rodzaju problemu. Skończyło się na użyciu kombinacji sugerowanych rozwiązań opisanych powyżej.
Po pierwsze, mam wiadro s3 z wieloma folderami, każdy folder reprezentuje stronę reagującą / reduxową. Używam również Cloudfront do unieważnienia pamięci podręcznej.
Musiałem więc użyć reguł routingu do obsługi 404 i przekierować je do konfiguracji skrótu:
W moim kodzie js musiałem obsługiwać go za pomocą
baseName
konfiguracji routera reagującego. Przede wszystkim upewnij się, że twoje zależności są interoperacyjne, mam zainstalowane, z którymihistory==4.0.0
był niezgodnyreact-router==3.0.1
.Moje zależności to:
Utworzyłem
history.js
plik do ładowania historii:Ten fragment kodu pozwala obsłużyć 404 wysłany przez serwer z mieszaniem i zastąpić je w historii ładowaniem naszych tras.
Możesz teraz użyć tego pliku do skonfigurowania sklepu i pliku głównego.
Mam nadzieję, że to pomoże. Zauważysz, że w tej konfiguracji używam wtryskiwacza redux i wtryskiwacza homebrew sagas do asynchronicznego ładowania javascript przez routing. Nie przejmuj się tymi liniami.
źródło
Możesz teraz to zrobić za pomocą Lambda @ Edge, aby przepisać ścieżki
Oto działająca funkcja lambda @ Edge:
W swoich zachowaniach w chmurze zmodyfikujesz je, aby dodać wywołanie do tej funkcji lambda w „Żądaniu przeglądarki”
Pełny samouczek: https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/
źródło
return callback(null, request);
Jeśli wylądowałeś tutaj, szukając rozwiązania współpracującego z React Router i konsolą AWS Amplify - już wiesz, że nie możesz bezpośrednio korzystać z reguł przekierowania CloudFront, ponieważ Amplify Console nie ujawnia dystrybucji CloudFront dla aplikacji.
Rozwiązanie jest jednak bardzo proste - wystarczy dodać regułę przekierowywania / przepisywania w konsoli Amplify w następujący sposób:
Zobacz poniższe linki, aby uzyskać więcej informacji (i regułę przyjazną dla kopiowania ze zrzutu ekranu):
źródło
Sam szukałem odpowiedzi na to pytanie. S3 wydaje się obsługiwać tylko przekierowania, nie można po prostu przepisać adresu URL i po cichu zwrócić inny zasób. Zastanawiam się nad użyciem skryptu kompilacji do wykonania kopii mojego pliku index.html we wszystkich wymaganych lokalizacjach ścieżek. Może to też zadziała dla ciebie.
źródło
Żeby ująć niezwykle prostą odpowiedź. Wystarczy użyć strategii lokalizacji skrótu dla routera, jeśli hostujesz na S3.
export const AppRoutingModule: ModuleWithProviders = RouterModule.forRoot (trasy, {useHash: true, scrollPositionRestoration: 'enabled'});
źródło