EDIT: I have added the response from OMDB
{Response: "False", Error: "Invalid API key!"}
Error: "Invalid API key!"
Response: "False"
I am new to web development and I am trying to build a chrome extension that displays imdb scores on netflix. I am using the OMDB API to do this. At first I got the following error:
"Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ''. This request has been blocked; the content must be served over HTTPS.",
however I just changed the "http" in the url to "https" and it went away. However, now I am getting a 401 error, which I think means my access is being denied. This is a picture of the full error
Here is the code for the extension
Manifest file:
{
"manifest_version": 2,
"name": "1_ratings_netflix",
"version": "0.1",
"description": "Display imdb ratings on netflix",
"content_scripts": [
{
"matches": [
"https://www.netflix.com/*", "https://www.omdbapi.com/*"
],
"js": ["content.js"]
}
],
"icons": { "16": "icon16.png", "48":"icon48.png"},
"permissions": [
"https://www.netflix.com/*", "https://www.omdbapi.com/*"
]
}
Content File:
function fetchMovieNameYear() {
var synopsis = document.querySelectorAll('.jawBone .jawbone-title-link');
if (synopsis === null) {
return;
}
var logoElement = document.querySelectorAll('.jawBone .jawbone-title-link .title');
if (logoElement.length === 0)
return;
logoElement = logoElement[logoElement.length - 1];
var title = logoElement.textContent;
if (title === "")
title = logoElement.querySelector(".logo").getAttribute("alt");
var titleElement = document.querySelectorAll('.jawBone .jawbone-title-link .title .text').textContent;
var yearElement = document.querySelectorAll('.jawBone .jawbone-overview-info .meta .year');
if (yearElement.length === 0)
return;
var year = yearElement[yearElement.length - 1].textContent;
var divId = getDivId(title, year);
var divEl = document.getElementById(divId);
if (divEl && (divEl.offsetWidth || divEl.offsetHeight || divEl.getClientRects().length)) {
return;
}
var existingImdbRating = window.sessionStorage.getItem(title + ":" + year);
if ((existingImdbRating !== "undefined") && (existingImdbRating !== null)) {
addIMDBRating(existingImdbRating, title, year);
} else {
makeRequestAndAddRating(title, year)
}
};
function addIMDBRating(imdbMetaData, name, year) {
var divId = getDivId(name, year);
var divEl = document.getElementById(divId);
if (divEl && (divEl.offsetWidth || divEl.offsetHeight || divEl.getClientRects().length)) {
return;
}
var synopsises = document.querySelectorAll('.jawBone .synopsis');
if (synopsises.length) {
var synopsis = synopsises[synopsises.length - 1];
var div = document.createElement('div');
var imdbRatingPresent = imdbMetaData && (imdbMetaData !== 'undefined') && (imdbMetaData !== "N/A");
var imdbVoteCount = null;
var imdbRating = null;
var imdbId = null;
if (imdbRatingPresent) {
var imdbMetaDataArr = imdbMetaData.split(":");
imdbRating = imdbMetaDataArr[0];
imdbVoteCount = imdbMetaDataArr[1];
imdbId = imdbMetaDataArr[2];
}
var imdbHtml = 'IMDb rating : ' + (imdbRatingPresent ? imdbRating : "N/A") + (imdbVoteCount ? ", Vote Count : " + imdbVoteCount : "");
if (imdbId !== null) {
imdbHtml = "<a target='_blank' href='https://www.imdb.com/title/" + imdbId + "'>" + imdbHtml + "</a>";
}
div.innerHTML = imdbHtml;
div.className = 'imdbRating';
div.id = divId;
synopsis.parentNode.insertBefore(div, synopsis);
}
}
function getDivId(name, year) {
name = name.replace(/[^a-z0-9\s]/gi, '');
name = name.replace(/ /g, '');
return "aaa" + name + "_" + year;
}
function makeRequestAndAddRating(name, year) {
var url = "https://www.omdbapi.com/?i=tt3896198&apikey=**{API_KEY}**" + encodeURI(name)
+ "&y=" + year + "tomatoes=true";
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function () {
if (xhr.status === 200) {
var apiResponse = JSON.parse(xhr.responseText);
var imdbRating = apiResponse["imdbRating"];
var imdbVoteCount = apiResponse["imdbVotes"];
var imdbId = apiResponse["imdbID"];
var imdbMetaData = imdbRating + ":" + imdbVoteCount + ":" + imdbId;
window.sessionStorage.setItem(name + ":" + year, imdbMetaData);
window.sessionStorage.setItem("metaScore:" + name + ":" + year, metaScore)
window.sessionStorage.setItem("rotten:" + name + ":" + year, rottenRating);
addIMDBRating(imdbMetaData, name, year);
addRottenRating(rottenRating, name, year);
addMetaScore(metaScore, name, year);
}
};
xhr.send();
}
if (window.sessionStorage !== "undefined") {
var target = document.body;
// create an observer instance
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
window.setTimeout(fetchMovieNameYear, 5);
});
});
// configuration of the observer:
var config = {
attributes: true,
childList: true,
characterData: true
};
observer.observe(target, config);
}
It would be helpful for you to post the request and response for OMDB (you can find them in the "Network" tab in dev tools).
One thing that triggers CORS (cross-origin requests) errors is specifying a content type other than application/x-www-form-urlencoded
, multipart/form-data
or text/plain
. If I recall correctly, the OMDB API will return a JSON response even without specifying the content type of the request, so you should try removing the line:
xhr.setRequestHeader('Content-Type', 'application/json');
More on "Simple Requests" which do not trigger CORS: https://javascript.info/fetch-crossorigin#simple-requests
You also need to get an API key (https://www.omdbapi.com/apikey.aspx) and replace
**{API_KEY}**
in your code with the key. You also need to add the t
key to your querystring or the title will be appended to your API key.
var url = "https://www.omdbapi.com/?i=tt3896198&apikey=**{API_KEY}**" + "&t="
+ encodeURI(name) + "&y=" + year + "tomatoes=true";