S3 정적 웹 사이트 호스팅 Index.html에 모든 경로 라우팅


250

S3을 사용하여 HTML5 pushStates를 사용하는 자바 스크립트 앱을 호스팅하고 있습니다. 문제는 사용자가 URL을 북마크하면 아무 것도 해결되지 않습니다. 내가 필요한 것은 전체 리디렉션을 수행하는 대신 모든 URL 요청을 가져 와서 S3 버킷에 루트 index.html을 제공하는 기능입니다. 그런 다음 내 자바 스크립트 응용 프로그램은 URL을 구문 분석하고 적절한 페이지를 제공 할 수 있습니다.

리디렉션하지 않고 모든 URL 요청에 대해 index.html을 제공하도록 S3에 지시하는 방법이 있습니까? https://stackoverflow.com/a/10647521/1762614 와 같이 단일 index.html을 제공하여 모든 수신 요청을 처리하도록 아파치를 설정하는 것과 유사합니다 . 이 경로를 처리하기 위해 웹 서버를 실행하지 않는 것이 좋습니다. S3에서 모든 것을하는 것은 매우 매력적입니다.


이것에 대한 해결책을 찾았습니까?
w2lame

답변:


301

CloudFront 도움말을 사용하면 URL 해킹없이 쉽게 해결할 수 있습니다.

  • S3 버킷 생성 (예 : react)
  • 다음 설정으로 CloudFront 배포를 생성하십시오.
    • 기본 루트 객체 : index.html
    • 오리진 도메인 이름 : S3 버킷 도메인 (예 : react.s3.amazonaws.com)
  • 오류 페이지 탭으로 이동하여 사용자 정의 오류 응답 작성을 클릭하십시오 .
    • HTTP 오류 코드 : 403 : 금지됨 (404 : S3 정적 웹 사이트의 경우 찾을 수 없음)
    • 오류 응답 사용자 정의 : 예
    • 응답 페이지 경로 : /index.html
    • HTTP 응답 코드 : 200 : 확인
    • 만들기를 클릭 하십시오

8
감사. 지금까지 가장 좋은 답변입니다.
jgb

명확하지 않은 부분은 위치를 유지하므로 "자연스러운"라우팅을 수행 할 수 있습니다.
Lukasz Marek Sielski

5
이 나를 위해 마법처럼 일했다, 내가 필요한 경우에만 사용자 지정 오류 코드는 404 (403)이 아니었다
제레미 S.

4
약간의 해킹이지만 훌륭하게 작동합니다.

3
이것은 나를 위해 작동하지 않습니다. 이 솔루션은 항상 올바른 페이지가 아닌 홈 페이지로 리디렉션됩니다.
Jim

201

이 작업을 수행하는 방법은 다음과 같습니다.

에서 편집 리디렉션 규칙 도메인에 대한 S3 콘솔의 섹션에서 다음 규칙을 추가 :

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>yourdomainname.com</HostName>
      <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

그러면 경로의 해시 뱅 버전으로 404를 찾을 수없는 모든 경로가 루트 도메인으로 리디렉션됩니다. 그래서 http://yourdomainname.com/posts가 로 리디렉션됩니다 http://yourdomainname.com/#!/posts / 게시물에 어떤 파일이없는 제공.

그러나 HTML5 pushStates를 사용하려면이 요청을 가져와 해시 뱅 경로를 기반으로 적절한 pushState를 수동으로 설정해야합니다. 따라서 이것을 index.html 파일 맨 위에 추가하십시오.

<script>
  history.pushState({}, "entry page", location.hash.substring(1));
</script>

이것은 해시를 잡고 HTML5 pushState로 바꿉니다. 이 시점부터 pushStates를 사용하여 앱에 해시 뱅 경로가 아닌 경로를 가질 수 있습니다.


4
이 솔루션은 훌륭하게 작동합니다! 실제로 angularjs는 html 모드가 구성된 경우 자동으로 기록 pushState를 수행합니다.
wcandillon

1
URL에 GET 매개 변수가 포함되어 있으면 이전 버전의 IE에서는 실패합니다. 맞습니까? 그 문제를 어떻게 해결합니까?
clexmond

3
감사! 이것은 약간의 조정으로 백본에서 잘 작동했습니다. 이전 브라우저에 대한 수표를 추가했습니다 : <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>
AE Grey

10
성공 react-routerHTML5 pushStates 및 사용하여 해당 솔루션<ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
펠릭스 D.

5
그것은 사파리에서 작동하지 않으며 배포 전략에 큰 문제입니다. 리디렉션하기 위해 작은 js를 작성하는 것은 일종의 초라한 접근법입니다. 또한 리디렉션 수도 문제입니다. 모든 S3 URL이 항상 index.html을 가리키는 방법이 있는지 파악하려고합니다.
moha297

129

다른 사람들이 언급 한 S3 / 리디렉션 기반 접근 방식에는 거의 문제가 없습니다.

  1. Mutliple 리디렉션은 앱의 경로가 해결되면 발생합니다. 예 : www.myapp.com/path/for/test는 www.myapp.com/#/path/for/test로 리디렉션됩니다.
  2. '#'이 (가) SPA 프레임 워크의 작동으로 인해 URL 표시 줄에 깜박임이 있습니다.
  3. 서재응은 '이봐! 구글은 리디렉션에 손을 강제
  4. 앱에 대한 Safari 지원이 실패합니다.

해결책은 다음과 같습니다.

  1. 웹 사이트에 대해 색인 경로를 구성했는지 확인하십시오. 주로 index.html입니다
  2. S3 구성에서 라우팅 규칙 제거
  3. S3 버킷 앞에 Cloudfront를 배치하십시오.
  4. Cloudfront 인스턴스에 대한 오류 페이지 규칙을 구성하십시오. 오류 규칙에서 다음을 지정하십시오.

    • HTTP 오류 코드 : 404 (및 필요에 따라 403 또는 기타 오류)
    • 오류 캐싱 최소 TTL (초) : 0
    • 응답 사용자 정의 : 예
    • 응답 페이지 경로 : /index.html
    • HTTP 응답 코드 : 200

      1. SEO 필요 + index.html이 캐시되지 않도록하려면 다음을 수행하십시오.
    • EC2 인스턴스를 구성하고 nginx 서버를 설정하십시오.

    • EC2 인스턴스에 퍼블릭 IP를 할당하십시오.
    • 인스턴스로 생성 한 EC2 인스턴스가있는 ELB 생성
    • ELB를 DNS에 할당 할 수 있어야합니다.
    • 이제 다음 작업을 수행하도록 nginx 서버를 구성하십시오 : Proxy_pass 모든 요청을 CDN (index.html 전용, 클라우드 프론트에서 직접 다른 자산 제공) 및 검색 봇에 대해 Prerender.io와 같은 서비스에서 규정 한대로 트래픽을 리디렉션하십시오.

nginx 설정과 관련하여 더 자세한 정보를 얻을 수 있습니다. 메모 만 남겨 두십시오. 어려운 방법을 배웠습니다.

클라우드 프론트 배포판 업데이트가 완료되면 깨끗한 모드에 있도록 클라우드 프론트 캐시를 한 번 무효화하십시오. 브라우저에서 URL을 누르십시오. 모두 좋을 것입니다.


6
파일이 존재하지 않을 때 S3가 403 Forbidden으로 응답하므로 HTTP 오류 코드 403에 대해서도 위의 4 단계를 복제해야한다고 생각합니다.
Andreas

4
나에게 이것은 예상 된 (허용 된) 행동을 초래하는 유일한 대답이다
mabe.berlin

1
포인트 5의 @ moha297 기본적으로 nginx에서 가져 오기 위해 CDN에서 프록시하는 사이트를 구성하고 있습니까 (index.html 및 크롤러 요청 제외)? 이 경우 CDN 에지 서버의 이점을 잃지 않겠습니까?
Rahul Patel

2
@ moha297이 주석을 설명해 주시겠습니까? "CDN에서 index.html을 제공해서는 안됩니다"? CloudFront에서 S3의 index.html을 제공하는 데 문제가 없습니다.
Carl G

1
TTL 0을 처리하는 방법에 대한 자세한 내용은 stackoverflow.com/a/10622078/4185989 를 참조하십시오 (짧은 버전 : Cloudfront에 의해 캐시되지만 If-Modified-SinceGET 요청은 원본으로 전송 됨)-원하지 않는 사람들에게 유용한 고려 사항 5 단계에서와 같이 서버를 설정합니다.
jmq

18

접선이지만 S3에서 호스팅하려는 (HTML5) 브라우저 기록이있는 Rackt의 React Router 라이브러리 를 사용하는 사람들을위한 팁이 있습니다.

사용자가 방문하는 가정 /foo/bear하여 S3 호스팅 정적 웹 사이트를. David의 초기 제안을 감안할 때 리디렉션 규칙은로 보냅니다 /#/foo/bear. 응용 프로그램이 브라우저 기록을 사용하여 빌드 된 경우 별다른 효과가 없습니다. 그러나이 시점에서 애플리케이션이로드되어 이제 히스토리를 조작 할 수 있습니다.

프로젝트에 Rackt 히스토리 를 포함하여 ( React Router 프로젝트에서 사용자 정의 히스토리 사용 참조 ) 해시 히스토리 경로를 인식하는 리스너를 추가하고 다음 예에 표시된대로 경로를 적절하게 대체 할 수 있습니다.

import ReactDOM from 'react-dom';

/* Application-specific details. */
const route = {};

import { Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';

const history = useRouterHistory(createHistory)();

history.listen(function (location) {
  const path = (/#(\/.*)$/.exec(location.hash) || [])[1];
  if (path) history.replace(path);
});

ReactDOM.render(
  <Router history={history} routes={route}/>,
  document.body.appendChild(document.createElement('div'))
);

요약하자면:

  1. David의 S3 리디렉션 규칙이로 연결 /foo/bear됩니다 /#/foo/bear.
  2. 응용 프로그램이로드됩니다.
  3. 히스토리 리스너는 #/foo/bear히스토리 표기법 을 감지합니다 .
  4. 그리고 역사를 올바른 경로로 바꾸십시오.

Link태그 는 다른 모든 브라우저 기록 기능과 마찬가지로 예상대로 작동합니다. 내가 알아 차린 유일한 단점은 초기 요청에서 발생하는 전면 광고 리디렉션입니다.

이것은 AngularJS 솔루션 에서 영감을 얻었으며 모든 응용 프로그램에 쉽게 적용 할 수 있다고 생각합니다.


2
이것은 마이클에게 도움이되었습니다. 감사합니다! 기록에서 참조를 변경하고 BrowserHistory를 사용하고 싶을 수도 있습니다. 즉browserHistory.listen
Marshall Moutenot

천만에요! 기쁘다. 또한 동의 했으며이 특정 사용 사례에 대해 리 액트 라우터의 사용 중단 경고를 해결하기 위해 스 니펫을 업데이트했습니다.
Michael Ahlers

의 출시와 함께 v3.0.0 - 라우터 반응이 때문에 반응 라우터 v3.0.0는 역사 v3.0.0을하지 작업 사용 않습니다
VARAND Pezeshkian

역사를 막는 방법에 대한 아이디어가 있습니까? 무한한 통화 루프를 들으십니까? 내가 생각하는 경로를 교체하여 발생했습니다.
Mirko Flyktman

14

이 문제에 대한 4 가지 해결책이 있습니다. 처음 3 개는 이미 답변에 포함되어 있으며 마지막 3 개는 저의 공헌입니다.

  1. 오류 문서를 index.html로 설정하십시오.
    문제 : 응답 본문은 정확하지만 상태 코드는 404가되어 SEO에 피해를줍니다.

  2. 리디렉션 규칙을 설정하십시오.
    문제 : #!로드시 URL이 오염되어 페이지가 깜박입니다.

  3. CloudFront를 구성하십시오.
    문제 : 모든 페이지가 원본에서 404를 반환하므로 아무것도 캐시하지 않거나 (제안 된대로 TTL 0) 사이트를 업데이트 할 때 캐시하고 문제가있는 경우 선택해야합니다.

  4. 모든 페이지를 미리 렌더링하십시오.
    문제 : 페이지를 자주 변경하는 경우 페이지를 미리 렌더링하기위한 추가 작업 예를 들어 뉴스 웹 사이트입니다.

옵션 4를 사용하는 것이 좋습니다. 모든 페이지를 미리 렌더링하면 예상 페이지에 404 오류가 발생하지 않습니다. 페이지가 정상적으로로드되고 프레임 워크가 제어를 수행하고 정상적으로 SPA 역할을합니다. 오류 문서에 일반 error.html 페이지 및 404 오류를 404.html 페이지 (해시 뱅없이)로 리디렉션하도록 리디렉션 규칙을 표시하도록 설정할 수도 있습니다.

403 Forbidden errors에 대해서는 전혀 발생하지 않습니다. 내 응용 프로그램에서는 호스트 버킷 내의 모든 파일이 공개 되어 있으며 읽기 권한을 가진 모든 옵션으로 설정했습니다 . 사이트에 개인 페이지가있는 경우 HTML 레이아웃 을 볼 수있게하는 것은 문제가되지 않습니다. 보호해야 할 것은 데이터 이며 이는 백엔드에서 수행됩니다.

또한 사용자 사진과 같은 개인 자산이있는 경우 다른 버킷에 저장할 수 있습니다 . 개인 자산은 데이터 와 동일한 관리가 필요 하며 앱을 호스팅하는 데 사용되는 자산 파일과 비교할 수 없기 때문입니다.


1
귀하의 사이트에는 모든 페이지를 미리 렌더링하는 데 유용한 예제가 있습니다. zanon.io/posts/… .- 감사합니다
frekele

이 네 번째 방법은 pushState URL을 다시로드하는 사용자를 처리합니까? 탐색을 잘 처리하지만 다시로드하면 여전히 서버에 도달합니다.
Alpha

@Alpha, 귀하의 질문을 올바르게 이해했는지 확실하지 않지만 다시로드하면 새로운 요청으로 작동합니다. S3는 요청을 받고 사전 렌더링 된 페이지를 다시 반환합니다. 이 경우 서버가 없습니다.
Zanon

@Zanon Ah, 이해합니다. 미리 렌더링 된 페이지를 캐시하고 S3 존재하지 않는 리소스를 사용하지 않는 것이 좋습니다. 동적 요소가있는 경로를 제외 할 수 있습니다.
Alpha

1
@Zanon 마침내 이해합니다-감사합니다! 그렇습니다. :)
Alpha

13

오늘 같은 문제가 발생했지만 @ angularjs 응용 프로그램에서 hashbang을 제거하기 위해 @ Mark-Nutter의 솔루션이 불완전했습니다.

실제로 권한 편집 으로 이동하여 권한 추가를 클릭 한 다음 버킷 의 올바른 목록 을 모든 사람에게 추가 해야합니다. 이 구성을 사용하면 이제 AWS S3에서 404 오류를 반환 할 수 있으며 리디렉션 규칙이 올바르게 적용됩니다.

이처럼 : 여기에 이미지 설명을 입력하십시오

그런 다음 리디렉션 규칙 편집으로 이동 하여이 규칙을 추가 할 수 있습니다 .

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>subdomain.domain.fr</HostName>
            <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

SEO 목적으로 hashbang 메소드를 사용하지 않으면 HostName subdomain.domain.fr을 도메인 및 KeyPrefix #! /로 바꿀 수 있습니다 .

물론,이 모든 것은 각도 응용 프로그램에서 html5mode를 이미 설정 한 경우에만 작동합니다.

$locationProvider.html5Mode(true).hashPrefix('!');

이것에 대한 나의 유일한 문제는 당신이 nginx 규칙과 같은 것이없는 hashbang의 플래시가 있다는 것입니다. 사용자가 페이지에 있고 새로 고침 : / products / 1-> #! / products / 1-> / products / 1
Intellix

1
모든 사람에게 목록 권한을 부여하는 대신 403 오류에 대한 규칙을 추가해야한다고 생각합니다.
Hamish Moffatt

11

Angular 2+ 애플리케이션을 Amazon S3에서 제공하고 URL을 작동시키는 가장 쉬운 솔루션은 index.html을 S3 버킷 구성에서 Index 및 Error 문서로 지정하는 것입니다.

여기에 이미지 설명을 입력하십시오


11
이것은 엄청나게 내려진 답 과 같은 답이다 . 그것은 잘 작동하지만 body응답의 경우 에만 작동합니다 . 상태 코드는 404이며 SEO를 손상시킵니다.
Zanon

body가져 오는 스크립트가있는 경우 에만이 기능을 사용할 수 있기 때문에 head웹 사이트의 서브 루트에 직접 도달하면 작동하지 않습니다
Mohamed Hajr

4

문제가 여전히 있기 때문에 나는 다른 해결책을 던지지 만. 필자의 경우 [mydomain] / pull-requests / [pr number] /
(예 : www.example.com/pull-requests/822/ 에서 병합하기 전에 병합하기 전에 테스트를 위해 모든 풀 요청을 s3에 자동 배포하려고했습니다 . )

내가 아는 한 s3 규칙이 아닌 시나리오에서는 html5 라우팅을 사용하여 하나의 버킷에 여러 프로젝트를 가질 수 있으므로 대부분의 투표 제안은 루트 폴더의 프로젝트에서 작동하지만 자체 하위 폴더의 여러 프로젝트에서는 작동하지 않습니다.

그래서 나는 nginx 설정을 수행하는 서버를 도메인으로 지정했습니다.

location /pull-requests/ {
    try_files $uri @get_files;
}
location @get_files {
    rewrite ^\/pull-requests\/(.*) /$1 break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @get_routes;
}

location @get_routes {
    rewrite ^\/(\w+)\/(.+) /$1/ break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @not_found;
}

location @not_found {
    return 404;
}

파일을 가져 오려고 시도하지 않으면 html5 경로라고 가정하고 시도합니다. 찾을 수없는 경로에 대한 404 각도 페이지가있는 경우 @not_found로 이동하지 않고 찾을 수없는 파일 대신 각도 404 페이지를 반환합니다. @ get_routes 또는 if의 일부 규칙으로 고정 될 수 있습니다.

나는 nginx 설정 영역에서 너무 편안하지 않다고 말하고 그 문제에 대해 정규 표현식을 사용하고 있습니다.이 시행 착오로 작업했습니다. 그래서이 작업을 수행하는 동안 개선의 여지가 있다고 확신하고 의견을 공유하십시오 .

참고 : S3 구성에 s3 리디렉션 규칙이 있으면 제거하십시오.

btw는 Safari에서 작동합니다.


안녕하세요 .. 솔루션 주셔서 감사합니다 ... s3 배포를 위해이 nginx conf 파일을 어디에 넣습니까? .exextensions 폴더를 만들어 proxy.config 파일에 저장 해야하는 탄력적 beantalk와 동일합니까?
user3124360

@ user3124360 Elastic BeanStack에 대해 잘 모르지만 제 경우에는 도메인 이름을 ec2 인스턴스로 지정하고 nginx 구성을 가지고 있습니다. 따라서 요청은 CLIENT-> DNS-> EC2-> S3-> CLIENT로 이동합니다.
앤드류 Arnautov

네, nginx 설정으로 github.com/davezuko/react-redux-starter-kit/issues/1099 와 매우 비슷한 일을하고 있습니다 ... conf 파일을 게시 해 주셔서 감사합니다 .. 어떻게이 EC2- > S3 연결 지금
user3124360

3

같은 종류의 문제를 찾고있었습니다. 위에서 설명한 제안 솔루션을 혼합하여 사용했습니다.

먼저 여러 폴더가있는 s3 버킷이 있으며 각 폴더는 react / redux 웹 사이트를 나타냅니다. 또한 캐시 무효화를 위해 cloudfront를 사용합니다.

따라서 404를 지원하기 위해 라우팅 규칙을 사용하고 해시 구성으로 리디렉션해야했습니다.

<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website1/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website1#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website2/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website2#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website3/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website3#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

내 js 코드에서 baseNamereact-router 구성 으로 처리해야했습니다 . 우선, 반드시 의존성이 상호 운용 할, 내가 설치 한 history==4.0.0호환이었다 느릅 나무 react-router==3.0.1.

내 의존성은 다음과 같습니다

  • "역사": "3.2.0",
  • "반응": "15.4.1",
  • "react-redux": "4.4.6",
  • "반응 라우터": "3.0.1",
  • "react-router-redux": "4.0.7",

history.js기록을로드하기위한 파일을 만들었습니다 .

import {useRouterHistory} from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';

export const browserHistory = useRouterHistory(createBrowserHistory)({
    basename: '/website1/',
});

browserHistory.listen((location) => {
    const path = (/#(.*)$/.exec(location.hash) || [])[1];
    if (path) {
        browserHistory.replace(path);
    }
});

export default browserHistory;

이 코드는 서버가 보낸 404를 해시로 처리하고 경로를로드하기 위해 기록에서 대체합니다.

이제이 파일을 사용하여 상점 및 루트 파일을 구성 할 수 있습니다.

import {routerMiddleware} from 'react-router-redux';
import {applyMiddleware, compose} from 'redux';

import rootSaga from '../sagas';
import rootReducer from '../reducers';

import {createInjectSagasStore, sagaMiddleware} from './redux-sagas-injector';

import {browserHistory} from '../history';

export default function configureStore(initialState) {
    const enhancers = [
        applyMiddleware(
            sagaMiddleware,
            routerMiddleware(browserHistory),
        )];

    return createInjectSagasStore(rootReducer, rootSaga, initialState, compose(...enhancers));
}
import React, {PropTypes} from 'react';
import {Provider} from 'react-redux';
import {Router} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import variables from '!!sass-variable-loader!../../../css/variables/variables.prod.scss';
import routesFactory from '../routes';
import {browserHistory} from '../history';

const muiTheme = getMuiTheme({
    palette: {
        primary1Color: variables.baseColor,
    },
});

const Root = ({store}) => {
    const history = syncHistoryWithStore(browserHistory, store);
    const routes = routesFactory(store);

    return (
        <Provider {...{store}}>
            <MuiThemeProvider muiTheme={muiTheme}>
                <Router {...{history, routes}} />
            </MuiThemeProvider>
        </Provider>
    );
};

Root.propTypes = {
    store: PropTypes.shape({}).isRequired,
};

export default Root;

도움이 되길 바랍니다. 이 구성에서 라우팅을 통해 자바 스크립트를 비동기 적으로로드하기 위해 redux 인젝터와 homebrew sagas 인젝터를 사용합니다. 이 줄에 신경 쓰지 마십시오.


3

이제 Lambda @ Edge를 사용하여 경로를 다시 작성할 수 있습니다.

작동하는 lambda @ Edge 함수는 다음과 같습니다.

  1. 새로운 Lambda 함수를 생성하되 빈 함수 대신 기존 블루 프린트 중 하나를 사용하십시오.
  2. "cloudfront"를 검색하고 검색 결과에서 cloudfront-response-generation을 선택하십시오.
  3. 함수를 만든 후 내용을 아래로 바꿉니다. Cloudfront가 작성 당시 노드 12를 지원하지 않았기 때문에 노드 런타임을 10.x로 변경해야했습니다.
'use strict';
exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to Lambda@Edge 
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;

    return callback(null, request);
};

클라우드 프론트 비헤이비어에서 "뷰어 요청"에서 해당 람다 함수에 대한 호출을 추가하도록이를 편집합니다. 여기에 이미지 설명을 입력하십시오

전체 자습서 : https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/


1
코드 예제는 한 줄만 return callback(null, request);
빠졌습니다

2

React Router 및 AWS Amplify Console에서 작동하는 솔루션을 찾고 있다면 Amplify Console이 앱에 CloudFront 배포를 노출하지 않기 때문에 CloudFront 리디렉션 규칙을 직접 사용할 수 없다는 것을 이미 알고 있습니다.

그러나 솔루션은 매우 간단합니다. Amplify Console에서 다음과 같이 리디렉션 / 다시 쓰기 규칙을 추가하면됩니다.

React Router에 대한 콘솔 재 작성 규칙 증폭

자세한 내용은 다음 링크를 참조하십시오 (스크린 샷의 복사하기 쉬운 규칙).


0

나는 이것에 대한 답을 찾고 있었다. S3는 리디렉션 만 지원하는 것으로 보이며 URL을 다시 쓰고 다른 리소스를 자동으로 반환 할 수는 없습니다. 빌드 스크립트를 사용하여 필요한 모든 경로 위치에 index.html 사본을 만드는 것을 고려하고 있습니다. 어쩌면 그것은 당신에게도 효과가있을 것입니다.


2
각 경로에 대한 색인 파일을 생성해도 마음에 들지 않았지만 example.com/groups/5/show 와 같은 동적 경로를 갖는 것은 어려울 것 입니다. 이 질문에 대한 내 대답을 보면 문제가 대부분 해결된다고 생각합니다. 그것은 약간의 해킹이지만 적어도 작동합니다.
Mark Nutter

nginx 서버 뒤에 배치하고 들어오는 모든 URL에 대해 index.html을 반환하는 것이 좋습니다. ember 앱의 heroku 배포 로이 작업을 성공적으로 수행했습니다.
moha297

-3

아주 간단한 대답을 드리겠습니다. S3에서 호스팅하는 경우 라우터의 해시 위치 전략을 사용하십시오.

export const AppRoutingModule : ModuleWithProviders = RouterModule.forRoot (routes, {useHash : true, scrollPositionRestoration : 'enabled'});

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.