Is it possible for CloudFront to cache REST API calls - caching

I have a Single Page Application, and would like to cache some of the public REST API calls. Is it possible to use CloudFront to cache the JSON result of those API calls?

You can point api.yourdomain.com to cloudfront domain. Cloudfront will cache the json response based on your cache control headers.
However, you'll likely have to deal with cross domain issue if your single page app is not served from api.yourdomain.com. Cloudfront supports OPTIONS request which means it should be able to support CORS. You can also enable caching of OPTIONS requests.
http://aws.amazon.com/cloudfront/faqs/#Does_Amazon_CloudFront_cache_POST_responses

Related

Cache assets from a CMS for offline PWA?

I'm writing a web media viewer for images/videos and I need to cache that media for offline use.
I have a manifest and service worker so it can be installed as a PWA, and I'm trying to cache media from a list of URLs with esentially:
let cache = await window.caches.open('pwa-assets');
for(let url of allAssetURLs) {
await cache.add(url);
}
This seems to work fine for local assets, but if those URLs are on a different domain (from a CMS/CDN) I get this CORS error.
Access to fetch at 'https://storage.googleapis.com/....appspot.com/...example.mp4' from origin 'https://127.0.0.1:4173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Web.dev has a note that cross-domain caching is possible here, but doesn't say much about it.
The URLs I'm trying to cache are for files store in google cloud storage, for example:
https://storage.googleapis.com/....appspot.com/...example.mp4
These do work if used in <img/> or <video/> tags, so I don't think it's a CORS header issue on the CDN.
You write:
These do work if used in <img/> or <video/> tags, so I don't think it's a CORS header issue on the CDN.
Loading such subresources across origins is by default compatible with the Same-Origin Policy (SOP) and doesn't trigger CORS errors. See the relevant section of the MDN Web Docs about the SOP:
Here are some examples of resources which may be embedded cross-origin: [...]
Images displayed by <img>.
Media played by <video> and <audio>.
You write:
This seems to work fine for local assets, but if those URLs are on a different domain (from a CMS/CDN) I get this CORS error.
Invoking the add method on a Cache results in a GET request. If its argument is on a different origin, the resource in question needs to be configured for CORS or you'll get a CORS error, as you've experienced. See the note in the relevant MDN Web Docs:
Note that for opaque filtered responses [...]
we can't access to [sic] the response headers, so this check
will always fail and the font won't be cached. [...]
It is something to keep in mind if you're attempting to
cache other resources from a cross-origin domain that
doesn't support CORS, though!
You write:
The URLs I'm trying to cache are for files store in google cloud storage, for example https://storage.googleapis.com/....appspot.com/...example.mp4.
This page of the Google Storage documentation explains how to configure CORS for your bucket(s), assuming those buckets are indeed yours. Otherwise, you're out of luck and won't be able to cache those resources on the client side.

How do API work with CORS policies to serve multiple apps

I am creating an API that would serve data to my frontend app. The API is on api.myapp.com and the app on www.myapp.com (same domain, just another subdomain). They communicate with AJAX requests and CORS is all set up, working fine.
But I have another app on another domain (www.myotherapp.com) which partialy uses the same data as myapp, so I was thinking of reusing the API so myotherapp could requests data from it too.
I think it is one use case of API, to be reusable, right?
But then, there is something that I may have missed, because as my API has CORS enabled with "Access-Control-Allow-Origin: www.myapp.com", it won't allow other apps to use its endpoints, right? Their AJAX requests would fail with CORS policies.
So how are public API built and configured? How should I set my API so it can serve several apps (ideally, only the ones I allow)?
Thanks for the explanations :)
There is an Origin header in the request and your API should check if this header is one of the allowed. If it is, then return it as an Access-Control-Allow-Origin header.
If the API is public, it can returns * as Access-Control-Allow-Origin header.

Prevent AJAX POST responses from being cached

I have AJAX POST requests generated from my webpage, and there may be multiple post requests with the same post data. But the response may vary, and I want to make sure I am not getting cached responses to any of these requests. I need each request to hit the webpage.
Am I right in assuming that responses to POST requests will not be cached?
There is two level of caching will be involved in that process
Browser caching
Server caching
To eliminate first one you have to cheat your browser and add a fake parameter to your ajax request so it will think it's unique each time i.e
www.example.com/api/ajax?123
www.example.com/api/ajax?1234
For server level you have to make sure that no cache been added to your configuration for such link, for example some developer will cache any file ends with .json or service like Cloud Flare it will automatically cache any static content.

Instructing browser cache to ignore certain URL params

I want the two iframes
<iframe src="www.URL.com?name=benny&runtime=1231231>
<iframe src="www.URL.com?name=benny&runtime=757847584>
which are loaded at different times to be mapped to the same cached value in the browser. The server has nothing to do with this. Basically, is there a way to have chrome, firefox, etc... cache api ignore certain parameters (in this case 'runtime') when looking up a src.
Passing a separate param or making a separate call for runtime will not work in the use case
That is not possible. You need to either remove parameters with different values from src or use XMLHttpRequest and blobs to request resource, and remove parameters from request URI using JavaScript. If you will use XMLHttpRequest you also need to consider Same-origin policy.
Browser cache key is a combination of HTTP method and URI. Query parameters are a part of an URI. Relevant excerpt from HTTP 1.1 specification:
The primary cache key consists of the request method and target URI.
However, since HTTP caches in common use today are typically limited
to caching responses to GET, many caches simply decline other methods
and use only the URI as the primary cache key.
For more information check New Tricks in XMLHttpRequest2 article by Eric Bidelman, XMLHttpRequest page, Blob Web APIs page and Same-origin policy page on MDN.
If you control server that serves your resources you can also adjust it to vary cache entries by certain parameters. For example in ASP.NET MVC you can use VaryByParam property of a OutputCache attribute. For more information check Improving Performance with Output Caching article by Microsoft ASP.NET team.

Does CORS affects localStorage?

Searched everywhere and didn't find straight answer.
Does CORS make cross-(sub)domain localStorage sharing possible or not?
And how about on IE8?
No, you cannot directly access another origin's storage, regardless of CORS settings.
You could however have a remote AJAX service that could store your settings on the remote domain.
e.g. Say your main website www.maindomain.com returns header Access-Control-Allow-Origin: https://www.subsite.com for its AJAX requests.
Then your other website www.subsite.com can make an AJAX request to e.g. https://www.maindomain.com/storage to retrieve or to save details cross-origin. The local storage for www.maindomain.com can be returned as a JSON object in the response for www.subsite.com to use.

Resources