简体   繁体   中英

Angular routing is not working with Cloudfront and S3

I have an angular 6 website hosted on S3 with S3 website hosting enabled. Also, I have a CloudFront distribution in front of it. I configured cloud front so that it redirects anything to index.html and responses with 200.

However, only "/" can be accessed using CloudFront. Other urls such as "/*" are not loading. Angular loads "/" this instead. As if angular sees only "/".

I added some code to log the url passed to angular and it turns out to be always "/".

Also, some other times "/*" urls don't even load "/" and I see this error on console "Uncaught SyntaxError: Unexpected token <".

Do you guys have any idea what could be causing this?

S3 Settings 在此处输入图片说明

Cloud front behavior:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

Please have a look at :how to deploy react and angular apps to S3/Cloudfront

Have you created a custom behavior for 403 (Forbidden) and 404 (not found) responses?

Every time that someone does a request to your website, for example, www.yourwebsite.com/ routeuri , note that this URI routeuri does not exist in your ORIGIN (which is S3 BUCKET), so your origin (S3 BUCKET) will return 403 response (Forbidden). So you should also added a custom error response for 403 status code, as shown in image below:

在此处输入图片说明

Please also make sure that your also added index.html as a Default Root Object in both Cloudfront and S3 Bucket as shown by images below:

Cloudfront 根对象 s3桶

I really recommend read official documentation to understand about CloudFront relationship with origin.

In my case this could be solved by adding index.html as the 'error document' under 'static website hosting'. Nothing else.

There are two possibilities:

(1) If your Angular on AWS S3 is client-side-rendered then every time you refresh your website your browser will send a request to AWS CloudFront to acquire the file from AWS S3.

eg. Reloading https://yourdomain.com/contact will actually sending a request to AWS S3 bucket > 'contact' directory > index.html, which is not existing because the page you're viewing is purely generated at client side.

Solution: CloudFront distribution > Error Pages > Create Custom Error Response > Create your custom responses for Error 400, 403, 404.

For example, an custom error response for Error 400:

HTTP Error Code: 400 Bad Request
Error Caching Minimum TTL: 300 
Customize Error Response: Yes
Response Page Path: /index.html
HTTP Response Code: 200 OK

(2) If your Angular is server-side-rendered, then you have to use your AWS S3 endpoint as the 'Origin Path Name' instead of the autocomplete from AWS dropdown list. For more details, you can refer to: Prerender Angular and Host It on AWS S3

This happened to me too and I fix it adding a custom error response in the CloudFront settings:

在此处输入图片说明

This happens because when you configure the CloudFront to be the only available access for the S3 bucket and you search /something, cloudfront will try to return that file to the user browser. Now the bucket is private and is only accessible from the CF, so this will return 403 or 404 error. To solve it, you need to return index.html when those errors happen.

Credits:https://lucasfsantos.com/posts/deploy-react-angular-cloudfront/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM