when I delete the image from my graphql server and using uploader.upload.destroy(public_id), it deletes from media library of cloudinary (https://cloudinary.com/console/media_library/folders/%2F)
but image is still available If I access it via cloudinary endpoint (https://res.cloudinary.com/db9rcrnuw/image/upload/v1576054005/47122.png)
I want to destroy those endpoints as well when the image is deleted.
here, screen.basePath means public_Id of the image
const screen = await ctx.prisma
.deleteScreen({
id: args.screenId
})
.$fragment(fragment);
if (scrn.basePath.length === 5) {
console.log(scrn.basePath.length);
cloudinary.uploader.destroy(screen.basePath, function(error, result) {
console.log(result, error);
});
return screen;
}
The short answer is that this is caused by a combination of not using the 'invalidate' parameter in your destroy API call and a difference between which URL format (i.e. with a version number (v123456789), 'v1' or no version number) the resource is accessed using versus what format your account is configured to send for invalidation.
The first thing to do is ensure that all destroy API calls include the 'invalidate' parameter set to 'true' if you'd like CDN invalidation.
Regarding the URL formats;
The 'v1576054005' that is part of delivery URLs is a version number that is essentially the UNIX timestamp of the upload time of the asset. Its main purpose is to always return the latest image and avoid CDN caching (upload API responses return the URL with the latest upload version). A bit more information on this topic can be found in this article - https://support.cloudinary.com/hc/en-us/articles/202520912-What-are-image-versions.
Please note that there are three possible URL formats Cloudinary can send for invalidation at the CDN, and these are outlined here: https://support.cloudinary.com/hc/en-us/articles/360001208732-What-URL-conventions-are-invalidated
Invalidation requests are sent when you delete or overwrite an image using the Media Library UI, or when you use the SDK/API, and also provide the 'invalidate' parameter, set to 'true'.
By default, all accounts send invalidations for the default format of URL which the SDKs produces, which uses no version number for assets in the root of your account, and a 'v1' placeholder for assets in folders (option 1 from the URL above).
If you were accessing the image with the full version component then that isn't sent for invalidation by default and why you are likely getting a cached copy returned.
In your case, the URL that would've been sent for invalidation would be without a version component (as the resource is in the root folder) i.e.
https://res.cloudinary.com/db9rcrnuw/image/upload/47122.png
Depending on how you are building your URLs, i.e., if you're using the SDK helper methods, taking the URL from the url or secure_url fields of the Upload API response (which use the full version number), will determine the format and thus how your account should be configured to invalidate.
I suggest you to email Cloudinary support (support#cloudinary.com) and share a link to this thread as well as some details on how the URLs you're using are generated so that your account can be configured accordingly.
Related
I am trying to implement the IIIF standard in order to show some papyri. I have configured Loris as an image server (here there is an info.json example: https://philhist-papyri-01.philhist.unibas.ch/loris/1/images/1.RectoIliad19th(T)book-IR-enh.jpg/info.json) and also I have configured Mirador. I am also serving manifests via an API (example: https://philhist-papyri-01.philhist.unibas.ch/api/iiif/11b4ca60-6bac-11eb-a1e6-005056b34690/manifest).
When I try to load the images in Mirador, I am getting an error:
Tile push../node_modules/openseadragon/build/openseadragon/openseadragon.js.$.Tile failed to load: https, https://philhist-papyri-01.philhist.unibas.ch, philhist-papyri-01.philhist.unibas.ch/6%2Fimages%2F6.VersoUnidentifiedLiteraryText-IR.jpg/full/4,/0/default.jpg - error: Image load aborted
Does anybody have any idea why this is coming from? The image actually can be retrieved from the URI in the manifest (https://philhist-papyri-01.philhist.unibas.ch/loris/1/images/1.RectoIliad19th(T)book-IR-enh.jpg/full/full/0/default.jpg), but it is not being shown in the mirador window.
There might be an issue with the resolver of Loris which is causing the #id of the image not to be canonical, but I am not quite sure.
I'm seeing an issue that perhaps CORS is not enabled for your info.json responses.
See: https://projectmirador.org/embed/?iiif-content=https://philhist-papyri-01.philhist.unibas.ch/api/iiif/11b4ca60-6bac-11eb-a1e6-005056b34690/manifest
Depending on how you use Loris to serve content, you will need to enable CORS for the IIIF requests.
I am using "caches" to cache in service worker my PWA assets and make it available offline.
When I change an asset, specifically a js file, I modify at least one byte in my service worker to trigger its native update: the service worker updates and retrieves all of its previously cached assets to refresh its caches.
Yet, server responds with a cached version of the file, and whereas I own the files served I have no control over Cache-Control http header.
How can i prevent browser caching on service worker cached resources? Versioning the files with a
"?v="+version
suffix won't work, because this version cannot be passed to the or or tags that references the cached files in html files, which are static and caches will not recognize and serve offline unversioned file names.
Since "caches.addAll" does not allow AFAIK any means to specify http request headers such as Cache-Control as fetch or XMLHttpRequest do, how can I prevent additional aggressive caching stages over my assets?
I am using plain Javascript and if possible I need it to be done without any additional library. Note also that meta http-equiv tags won't solve the problem for assets other than complete html.
You can bypass the browser's cache by explicitly constructing a Request object with a cache property set to an appropriate cache mode. 'reload' is a good choice, as it will bypass the browser's cache for the outgoing request, but it will update the browser's cache with the response (so you'll have a fresher browser cache overall). If you don't even want that update to be performed, you could use 'no-store'.
Here's some code showing how to do this concisely for an array of URLs that could be passed in to cache.addAll():
async function addAllBypassCache(cacheName, urls) {
const cache = await caches.open(cacheName);
const requests = urls.map((url) => new Request(url, {
cache: 'reload',
}));
await cache.addAll(requests);
}
The Strapi API responds the media URLs as something like "url:'/uploads/thumbnail.png'".
I would like to get the complete URL that links to my file as value for "url". For example: "url:'https://example.org/uploads/thumbnail.png'"
The documentation also shows the full URL as response. How can I achieve this?
The full URLs come from using an upload provider such as AWS-S3 or Cloudinary. The local provider doesn't support full URLs at the moment.
There are some potentials reasons why you shouldn’t store a full URL, and respond with a full URL. I won’t dive into those reasons.
I suggest creating the entire request/response, or creating a middleware component to intercept the response.
Then you can modify the original url value with the site’s URL. Looping through the results with something like:
const serverHost = strapi.config.get('server.host', 'defaultValueIfUndefined');
url = serverHost + url;
See the following docs for more details:
https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations.html
https://docs.strapi.io/developer-docs/latest/development/backend-customization/middlewares.html#implementation
I'm having trouble using the OutputCache attribute in Microsoft's MVC3 framework.
Please imagine the following controller action, which can be used as part of an AJAX call to get a list of products based on a particular manufacturerId:
public JsonResult GetProducts(long manufacturerId)
{
return Json(this.CreateProductList(manufacturerId), JsonRequestBehavior.AllowGet);
}
I want this result to be cached on the server to avoid making excessive database queries. I can achieve this by configuring the attribute thus:
[OutputCache(Duration = 3600, Location = OutputCacheLocation.Server, VaryByParam = "manufacturerId")]
This works as I expected - the browser makes an intitial request which causes the server to create and cache the result, subsequent requests from the same or different browser get the cached version.
But... I also want the browser to cache these results locally; if I filter first on manufacturer X, then Y then go back to X, I don't want it to make another request for X's products - I want it to just use its cached version.
I can make this happen, by changing the OutputCache to this:
[OutputCache(Duration = 3600, Location = OutputCacheLocation.Client)]
Here's the question: how do I combine these so that I can have both sets of behaviour? I tried setting the Location to ServerAndClient but this just made it behave the same as when Location was Server.
I'm sure that the problem has something to do with the "Vary: *" response header I get with ServerAndClient but I don't know how to get rid of it.
I welcome comments about the rationality of my intentions - the fact that I'm not getting the results I expect makes me think I might have some fundamental misunderstanding somewhere...
Many thanks.
PS: This is on a local dev environment, IIS Express from VS2010.
You can use OutputCacheLocation.Any which specifies
The output cache can be located on the browser client (where the
request originated), on a proxy server (or any other server)
participating in the request, or on the server where the request was
processed. This value corresponds to the HttpCacheability.Public
enumeration value.
You may want to also set Cache-control public to in the HTTP header for these requests.
Edit
It seems, depending on your .Net version of the web server you may need to include Response.Cache.SetOmitVaryStar(true); within your controller action to remove the Vary * headers as you suggest.
Details of the reason why in .Net 4 breaking changes release notes.
I am trying to localize Lenya publication URLs.
I store URL translation in the Document metadata and rewrite urls with URLRewriter transformator.
e.g. I build
/lenya/default/authoring/en/home
from
/lenya/default/authoring/index.html
But I can't find a simple way to force Lenya to tranlate incoming request URI back to the original path: /lenya/default/authoring/index.html
Really I want to process the request via pipelines using the original URL, not translated.
Is it possible at all? I had tried to add a servlet filter and use dispatcher, but filter can't access documents metadata because Environment object isn't in the processing stack yet at this stage...
(At this moment I see only one way - to update CocoonServlet and Cocoon classes)
Thanks!
I was able to do this via a RequestListener.
In the public void onRequestStart(Environment environment) method I create RequestWrapper with a new real URL and put it into objectModel. Also I change Environment context with a real URL: env.setContext("", realUrl, env.getContext())
This works fine!