We are having issues trying to make working a SPA with a client router (react router). We are using the concept of have a DOMAIN -> CDN (CloudFront) -> S3
for serving our static files.
We have configured the S3 for serving static files. The CDN are configured to have the origin from the S3 and we have configured custom error pages to catch errors:
with this configuration we can catch errors like this:
https://www.example.com/custom-url
The CDN will redirect all the 404/403 errors to the main index.html
and react router
will get the correct routing.
We have working our site, and the client router is working fine, but we have a problem with the response of our CDN with x-cache: Error from cloudfront
:
If we access to the main url https://www.example.com
without any query param (not query string) all works fine.
How can I solved this problem and make that all my dynamic URLs work?
Thanks.
If the X-Cache header is "Miss from cloudfront," then the request was retrieved from the origin and wasn't served by the cache. Review the Cache-Control header in the response. If the value for Cache-Control is "no-store," then the header is directing CloudFront to not cache the response.
Resolution. CloudFront returns "X-Cache:Miss from cloudfront" when the request is sent to the origin. CloudFront returns "X-Cache:Hit from cloudfront" when requests are served from the closest edge location. "Miss" requests might be slower to load because of the additional step of forwarding to the origin.
Configuration on the origin On your custom origin web server application, add Cache-Control no-cache, no-store, or private directives to the objects that you don't want CloudFront to cache. Or, add Expires directives to the objects that you don't want CloudFront to cache.
When you visit http://mywebsite.com
the request will hit the index.html
file in S3. Then you might click a button and go to http://mywebsite.com/stats
which is an internal route of your SPA app. Thus, it will not trigger any backend request.
But if you reload the page, http://mywebsite.com/stats
will be sent to S3 as your browser does not know that you are running an SPA frontend.
S3 will return 403 error with index.html and Cloudfront will send you the error.
Solution is using an edge lambda function in Cloudfront. Here an example:
const path = require('path')
exports.handler = (evt, ctx, cb) => {
const {request} = evt.Records[0].cf
if (!path.extname(request.uri)) {
request.uri = '/index.html'
}
cb(null, request)
}
Source: https://hackernoon.com/how-to-host-a-single-page-application-with-aws-cloudfront-and-lambda-edge-39ce7b036da2
Amazon CloudFront can get tricky with its configuration and debugging an error code - to trace it back to its root cause can take several hours. However, you might want to make the following checks before you get into the logs.
The bucket names should match the names of the website that you are hosting.
For instance, to host your-domain.com website on Amazon S3, you would create a bucket named your-domain.com.
To host a website under www.your-domain.com, you would name the bucket www.your-domain.com.
Its a best practice, to create buckets for both your-domain.com and www.your-domain.com.
Use the existing logic in your settings/configuration for any one of these buckets and use it to serve the static website. Use the other bucket to redirect the request to the original bucket.
Honestly, this wouldn't be causing you the trouble since you've integrated your system with Amazon CloudFront, which can be configured to use an Amazon S3 bucket of any name.
With Amazon CloudFront, users that visit your domain will directly fetch data from the CloudFront distribution which in turn caches contents from our S3 bucket.
While creating a distribution with Amazon CloudFront make note of the associated Amazon S3 endpoint with the Origin Domain Name. Make sure to use the web site endpoint and NOT the REST endpoint. Don't use the endpoint auto-suggested by CloudFront.
There is a difference in the behavior as explained in the Amazon Web Services official documentation
From your console logs, it suggests distribution instance is trying to access a forbidden element, page or resource and hence the 403 status code.
While the 404 is merely a result of page not found. However, after the error redirection - as handled in your configuration, the user is redirected back to index.html
where it encounters the 403.
More information on - How CloudFront Processes and Caches HTTP 4xx and 5xx Status Codes from Your Origin
As mentioned in the beginning it can get quite perplexing while tracking such errors. Let us know if the above helps. Also, I would really appreciate it if you could post updates on your investigations and findings.
Thanks for the read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With