vue.jscanvascorsviteimage-loading

How to configure the CORS on the Vite server to remove the CORS error when loading images


I have a Vite/Vue 3 application where I get an error like this when loading images.

Access to image at 'https://website.com/image-url.jpg' from origin 'https://my-web-app-url.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

The function that loads images looks like this:

const imageLoader = (image: HTMLImageElement, url: string): Promise<HTMLImageElement> => {
  return new Promise((resolve, reject) => {
    image.crossOrigin = "Anonymous";
    image.src = url;
    image.onload = () => resolve(image);
    image.onerror = () => reject(image);
  });
};

I need to load an image in order to create a canvas with the loaded image, this function looks like this:

const createCanvas = async (url: string): Promise<CanvasObject | null> => {
  const image = new Image();
  const loaded = await imageLoader(image, url);
  const canvas = document.createElement("canvas");
  canvas.setAttribute("visibility", "hidden");
  canvas.width = loaded.width;
  canvas.height = loaded.height;
  const ctx = canvas.getContext("2d");
  if (ctx) {
    ctx.drawImage(image, 0, 0);
    return { ctx, width: image.width, height: image.height };
  } else {
    console.error("context not found");
    return null;
  }
};

What i've already try:

  1. Set image cross origin like this:

image.crossOrigin = "Anonymous"

  1. Passing dummy query params to url like this (which disables image caching, as I understand it):

image.src = url + "?" + new Date().getTime()

  1. Enable cors and set cors origin to "*" in vite.config:
  server: {
    cors: { origin: "*" },
  }
  1. Add proxy rules to vite.config:
  server: {
    proxy: {
      "/": {
        target: "https://image-aware-background.vercel.app",
        changeOrigin: true,
        secure: false,
        rewrite: (path) => path.replace(/^\//, ""),
      },
    },
  }

But none of these methods helped me to solve the CORS error.

I see the access-control-allow-origin header in the original application request, but it is not in the image download request.

How to reproduce issue:

  1. go to https://image-aware-background.vercel.app/
  2. open dev console
  3. paste any image link (just press ctrl+v on the page)
  4. сheck the error in the console

Solution

  • Okay, I was able to figure it out after all, thanks to Ali Bahrami.

    If you need to download an image from a server that has a strictly configured CORS, you need to use a proxy server, which will return the data to you with the required headers.

    I used https://allorigins.win/. You need to put the address of the proxy server at the beginning of your url.

    https://api.allorigins.win/raw?url=https://example.org/
    

    So, my image loader function started looking like this:

    export const imageLoader = (image: HTMLImageElement, url: string): Promise<HTMLImageElement> => {
      return new Promise((resolve, reject) => {
        image.crossOrigin = "Anonymous";
        image.src = "https://api.allorigins.win/raw?url=" + url;
        image.onload = () => resolve(image);
        image.onerror = () => reject(image);
      });
    };