I am using an S3 bucket as static web solution to host a single page React application.
The react application works fine when I hit the root domain s3-bucket.amazon.com and the HTML5 history api works fine every time I click on a link the new url looks fine: _http://s3-bucket.amazon.com/entities/entity_id_
The problem happens when I use permalinks to access the application. Let's assume I am typing the same url (_http://s3-bucket.amazon.com/entities/entity_id_) in the browser I will get the following error from Amazon S3:
404 Not Found
Code: NoSuchKey
Message: The specified key does not exist.
Key: users
RequestId: 3A4B65F49D07B42C
HostId: j2KCK4tvw9DVQzOHaViZPwT7+piVFfVT3lRs2pr2knhdKag7mROEfqPRLUHGeD/TZoFJBI4/maA=
Is it possible to make Amazon S3 to work nicely with permalinks and HTML5 history api? Maybe it can act as proxy?
Thank you
Solution using AWS CloudFront:
Step 1: Go to CloudFront
Click on distribution id
Go to the Error page tab
Click on Create Custom Error Response
Step 2: Fill the form as
HTTP Error Code: 404
TTL: 0
Custom Error Response: Yes
Response Page Path: /index.html
HTTP Response Code: 200
source: https://medium.com/#nikhilkapoor17/deployment-of-spa-without-location-strategy-61a190a11dfc
Sadly S3 does not support the wildcard routing required for single page apps (basically you want everything after the host in the url to serve index.html, but preserve the route.
So www.blah.com/hello/world would actually serve www.blah.com/index.html but pass the route to the single page app.
The good news is you can do this with a CDN such as Fastly (Varnish) in front of S3. Setting up a rule such as:
if(req.url.ext == "" ) {
set req.url = "/index.html";
}
This will redirect all non asset requests (anything without a file extension) to index.html on the domain.
I have no experience running SPA on Amazon S3, but this seems to be a problem of url-rewriting.
It is one thing do have the history (html5) api rewrite your url when running your application / site.
But allowing rewritten urls to be accessible when refreshing or cold-surfing to your site definitely needs url-rewriting on a server level.
I'm thinking web.confg (IIS), .htaccess (Apache) or nginx site configuration.
It seems the same question already got asked some time ago: https://serverfault.com/questions/650704/url-rewriting-in-amazon-s3
Specify the same name for the index and error files on "Static website hosting" properties. See linked image 1.
Old question but simplest way would be to use hash routing. So instead of mydomain.com/somepage/subpage it would be mydomain.com/#/somepage/subpage
Related
I am trying to upload a Github action workflow via the Github V3 API.
I am trying to do the following to upload the main.yaml file to .github/workflows/main.yaml:
await this.put(`https://api.github.com/repos/${this.ownerName}/${this.repoName}/contents/.github/workflows/main.yaml`, {
message: title,
content,
sha,
branch: newBranch
})
It seems as though including the .github in the file path of the URL returns a 404. Is it possible to upload to a hidden directory? Maybe I need to escape the . somehow?
It might be that used personal access token (PAT) has insufficient permissions.
Slightly unintuitive, but to upload workflow files, the PAT needs to have a "Workflow" scope enabled too, not only have a write access to repo.
It is at tokens and looks like:
I serve my website using cloudfront s3 (static files). https://example.com
When I open particular url I want to get into the server, but stay on the same domain.
for example
https://example.com/index.html -> serve from cloudfront and s3
https://example.com/app.js -> serve from cloudfront and s3
https://example.com/foo -> go direct to my server (https://api.example.com/api/foo) and foo will return html content and in the browser is will stay and display the https://example.com/foo url.
Is something can be possible to do with s3 and cloudfront? if so what the configure I need to be done to achieve this?
You can setup a Cache behaviour for URL path which should go to Dynamic website
And a Default cache behaviour (A catch everything else) which should go to S3.
When you create a new distribution, you specify settings for the default cache behavior, which automatically forwards all requests to the origin(for you its S3) that you specify when you create the distribution. After you create a distribution, you can create additional cache behaviors that define how CloudFront responds when it receives a request for objects that match a path pattern (in your case /foo)
If you are doing it through CloudFormation then see AWS::CloudFront::Distribution CacheBehavior - AWS CloudFormation.
From Console
And Then
I'm a desktop developer that is trying to learn some web basics on the side. I've previously put together an asp.net mvc website that worked more or less okay and am currently working on a simpler, html/css/js only website.
A number of the pages on the website will contain images, with a number of pieces of data accompanying them, so I thought I'd put together a JSON with all of the data, including the links to the images and generate the image list on page load. The problem that I ran into is the JavaScript cross origin request when trying to fetch the JSON file.
I've looked around at solutions and most of them recommend spinning up a server - either asp.net or node.js to fetch the JSON from. Couple of questions:
If I can write HTML that references image files, why can I not fetch a json from javascript? Is there a fundamental piece of understanding that I'm missing here?
Is there any other way of using a JSON without spinning up a web server? Should I try embedding it into the HTML? Is that a bad idea?
Any other pointers/links to resources with relevant info :)
// My JavaScript:
<script>
$(document).ready(function(){
buildGallery('test.json', '#gallery');
});
// Builds a collection of thumbnails from the json specified inside of specified div
function buildGallery(jsonUrl, galleryDiv){
$.getJSON(jsonUrl, function(data){
// Ensure the data is in correct format
if (typeof(data) !== 'object'){
return;
}
// Build the gallery
$.each(data['images'], function(key, image){
var thumbnail = '<img src="' + image['url'] + '"/>'
$(galleryDiv).append(thumbnail);
});
});
}
</script>
This is based of: https://api.jquery.com/jQuery.getJSON/
Thanks heaps!
There are a couple issues with what you are trying to accomplish with the provided code.
First, you are trying to make an Ajax request to a resource that is not hosted on an http server. Ajax is a wrapper for XMLHttpRequest which was designed for fetching resources using the http protocol. However, it can support other protocols such as file, and ftp.
Second, CORS is not controlled by the browser, it's controlled by the http server. Cross domain origin requests can work, but only if the resource you are requesting responds with an http header that allows your domain to access it. Since the resource you are requesting has nothing to do with http, it will probably throw an error.
So why do images work using the file:// scheme? The <img/> tag supports loading resources using any scheme your browser cares to support. It turns out most browsers support it.
So I can't get json into my app without an http server!#? Yes and no. No because you usually cannot request a resource not served through an http server using XMLHttpRequest. However, you can still request resources through other means.
I recommend using the File API for reading files from the users filesystem.
We are integrating CKFinder with the CKEditor installation in PeopleSoft.
We created our own connector in Peoplesoft and almost everything is now working except editing image. It is stuck in the loading image dialog. We already implemented ImageInfo and the response is successfully received. In my observation, the following are the requests made by the browser.
caman.js [GET]
ImageInfo Command Request [GET]
(current URL)?camanproxyURL=(CKFinder Thumbnail Request URL) [GET]
(current URL)?camanproxyURL=(CKFinder ImagePreview Request URL) [GET]
I tried this in CKFinder demo but I don't see # 3 and #4 and the Thumbnail and ImagePreview were directly requested.
I think the problem here is in #3 and #4, the URL used is the current URL which is .../ckeditor/ckfinder/ckfinder.html. I don;t this is what supposed to happen.
How do I fix this issue? Is this something with our setup or configuration?
CKFinder is inside our CKEditor directory.
We're using custom CamanJS with some improvements. One of them was this change. It was due to similar problem with domain name that contain - in it's name. The fix changed a regexp that was used to tell if domain is local or remote (if a domain URL fails this regexp the proxy mechanism is used).
Could you verify that a domain URL that you are using for development passes this regex:
/(?:(?:http|https):\/\/)((?:[\w-]+)\.(?:(?:-|\w|\.)+))/
I had made a SPA in angularjs, when I run it on browser it showed me '#' in the address bar. So I enabled html5Mode. This successfully removed '#' from the url but when I try to reload the page, it gives 404: page not found error. I tried writing in .htaccess from this url:
htaccess redirect for Angular routes
Nothing change.
I also followed grunt answers but that was also not helpful.
Did you correctly enable html5 mode?
Take a look at the answer to a question regarding html5 mode/hashbang mode.
Did you add <base href="/"> to the head of your html?
You need to setup your server routes to return index file for all angular urls.
Usually you register your api at some special endpoint (as mysite.com/api/v1) and if url is not matching this pattern return index.html file with angular bootstrap logic.
This happens because without html5 mode all requests are sent to root server url (mysite.com/ even if link is mysite.com/#!/profile) but when you enable html5 mode, requests are sent as declared in angular so if you have '/' route with href to profile (/profile) and reload page from there (mysite.com/profile), request will be sent to mysite.com/profile and it will respond with 404 as it is setuped to return index file only for '/' url