Check if Youtube thumbnail exists using JavaScript fetch

Viewed 208

I know questions like that have been asked tons of times already but I still was not able to find a solution or even an explanation for that manner.

I work on a project that needs the best possible resolution on YouTube thumbnails. I used the following url https://i.ytimg.com/vi/VIDEOID/maxresdefault.jpg however I found out that on rare occasions this does not work and I get a placeholder image, and a status of 404, back. In that case I would like to use https://i.ytimg.com/vi/VIDEOID/hqdefault.jpg.

To check if an image exists I tried to make a fetch-request using JavaScript:

const url = "https://i.ytimg.com/vi/VIDEOID/hqdefault.jpg"
fetch(url).then(res => console.log(res.status))

But I get an error stating that the CORS-Header 'Access-Control-Allow-Origin' is missing. I tried setting it and several other headers I found but to no avail. It only works if I send the request in no-cors mode, but then the status is always 0 and all the other data seems to be missing aswell.

I also tested the request in Postman where it worked and even copied the JavaScript-Fetch-Snipped that Postman gave me:

var requestOptions = {
  method: 'GET',
  redirect: 'follow'
};

fetch("https://i.ytimg.com/vi/VIDEOID/maxresdefault.jpg", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

I read that this is a problem from the Server and Youtube is restricting this, but why does it work in Postman and why does it work when using <cfhttp> in ColdFusion? Also the status-code even shows up in the console within the CORS-Error message...

2 Answers

Why? explained:

The CORS policy is implemented in browsers to allow sharing resources between websites while preventing websites from attacking each other:

These policies only apply inside a browser. Presumably Postman and Coldfusion work because they are making direct HTTP requests outside the context of a browser script. Which leads to how to work-around CORS restrictions...

Solutions:

3 Ways to Fix the CORS Error — and How the Access-Control-Allow-Origin Header Works explains how to bypass CORS restrictions. They all work by manipulating the request headers/origin:

  1. Browser extension. (Not sure if this still works in 2022. Only works if user installs browser extension.)
  2. 3rd party request proxy. (The proxy linked in the demo is now limited due to abuse.)
  3. Build your own proxy.

Realistically, option #3 is the only real solution. SvelteKit endpoints make it super simple to proxy requests.

Following code is working properly for me and I am always getting 200 status ok Something similar implementation can be done

        //import fetch from 'node-fetch';
    const fetch = require('node-fetch');
    loaddata();
    async function loaddata(){
        var Headers="{headers: {'Access-Control-Allow-Origin': '*'}";
        var requestOptions = {
            method: 'GET',
            redirect: 'follow',

        };
        const response = await fetch('https://i.ytimg.com/vi/9DCwyuH29SI/hqdefault.jpg',requestOptions,Headers);
        console.log(response);
    }
Related