-2

I have looked through similar questions on here and none of the responses seemed to help as they aren't using vanilla JS. Hopefully someone here can help out. Note: also using IMDB API if that makes a difference. Really new to APIs and hoping this is just some stupid error on my part.

var searchButton = document.getElementById("searchBtn");
var navContainer = document.getElementById("navContainer");
var userInput = document.getElementById("charSearch");
var savedSearches = JSON.parse(localStorage.getItem("hero")) || [];
var currentSearch = savedSearches.length;
var imdbApiStart = "https://imdb-api.com/en/API/Search/"
var imdbKey = "k_zcmn64r8/";
var marvelApiStart =
  "https://gateway.marvel.com:443/v1/public/characters?apikey=";

var marvelKey = "public_key";
var marvelOtherKey = "my_private_key";
var ts = new Date().getTime();
var hash = ts +marvelKey+marvelOtherKey;
var passhash = CryptoJS.MD5(hash).toString();
console.log(passhash);

function getHeroInfo() {
  getMovieInfo(userInput.value);
  var requestUrl = marvelApiStart + marvelKey + "&hash=" + hash + "&name=" + userInput.value
  console.log(requestUrl);
  var result = fetch(requestUrl)
    .then(function (response) {
      return response.json();
    })
    .then(function (data) {
      console.log(data);
    });
    
  return result;
}


function postHeroInfo(data) {

}


searchButton.addEventListener("click", getHeroInfo);

https://developer.marvel.com/docs

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Paul Davis
  • 11
  • 4
  • Is `marvelKey` your API Key? If so, immediately remove if from the post as it is sensitive data. – Emiel Zuurbier Feb 23 '22 at 21:41
  • I don't think your URL is correct. Appending marvelApiStart and marvelKey will result in `...?nameStartsWith=382f5...` I would think you'd want `?nameStartsWith=Thor` or similar. – James Feb 23 '22 at 21:42
  • @James I think it should be `http://gateway.marvel.com/v1/public/characters?apikey=yourAPIKEY&nameStartsWith=...`. – Emiel Zuurbier Feb 23 '22 at 21:45
  • @EmielZuurbier just the public api key not the private, but ive edited it anway – Paul Davis Feb 23 '22 at 21:49
  • Looks like a typo, `marvelApiStart + marvelKey` will end up as `nameStartsWith=public_key`. You're not identifying a parameter as a key, so the API responds as as you're seeing. I'm voting to close as a typo. – Don't Panic Feb 23 '22 at 21:50
  • I've tried reordering and rewording multiple times. Even our TA couldn't help figure it out. What would be the correct way of stating it if it's a typo? @Don'tPanic – Paul Davis Feb 23 '22 at 21:59
  • @Don'tPanic even if i remove `nameStartsWith` parameter and add my `apikey=` it returns the same error – Paul Davis Feb 23 '22 at 22:10
  • The docs page you link to doesn't explicitly show how to use the key. But a search for "*marvel api key*" leads me [here](https://developer.marvel.com/documentation/authorization), which includes an example URL, which shows you use `apikey`. So in your code, `marvelApiStart` should be something like `"https://gateway.../characters?apikey=";`. Then `var requestUrl = marvelApiStart + marvelKey ...` will correctly add your key in the right place in the URL. It seems like you'd want to use only one of `nameStartsWith` or `name`, right? If so, you'll need to update that part of the URL too. – Don't Panic Feb 23 '22 at 22:10
  • OK - edit your question to include a [minimal, complete, and verifiable example](https://stackoverflow.com/help/mcve), so eg include the bare minimum HTML the JS references, and remove any JS that is not part of this problem (eg empty functions, the IMDB request I guess? Or is it the IMDB query that is returning the error? – Don't Panic Feb 23 '22 at 22:14
  • @Don'tPanic IMDB request isn't returning the error its the marvel API one that is. This is the bare minimum JS already. If i remove the IMDB request it returns a different error because getMovieInfo is within the getHeroInfo function. I will add the HTML though. – Paul Davis Feb 23 '22 at 22:23
  • There's more to it than the initial typo; I've retracted my close vote and added an answer. – Don't Panic Feb 23 '22 at 22:46

2 Answers2

1

There are a couple of simple problems in your code:

  1. You weren't passing a key (an edit has since corrected this);

  2. You're not hashing your hash string. The docs show that hash needs to be an md5 of the string timestamp + privateKey + publicKey. I searched for how to md5 a string in JS, and came across this SO answer with many options. I chose the first one, and used the linked md5 library. Sorry, I see you are of course hashing - you're just not using the hash you generate. Your requestUrl uses hash instead of the passhash you generated.

  3. You're not passing the ts parameter. The example in the docs shows you need to include that;

  4. You're using both nameStartsWith and name, AFAICT you should either one or the other, not both;

Fixing those things up, here is the basic JS to make a call to the API. The keys are fake, so the query does not work - but the error is what we should expect if we pass fake keys: The passed API key is invalid (click run to see it). If you copy-paste this code, and hardcode in your keys, it should work.

var marvelApiStart = "https://gateway.marvel.com:443/v1/public/characters?apikey=";
var marvelPublicKey = 'fake key';
var marvelPrivateKey = 'fake key';
var name = 'thor';
var ts = new Date().getTime();
var hash = md5(ts + marvelPrivateKey + marvelPublicKey);
var requestUrl = marvelApiStart + marvelPublicKey + "&ts=" + ts 
    + "&hash=" + hash + "&nameStartsWith=" + name;

console.log(requestUrl);

var result = fetch(requestUrl)
.then(function (response) {
    return response.json();
})
.then(function (data) {
    console.log(data);
});
<script src="https://www.myersdaily.org/joseph/javascript/md5.js"></script>
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
0

I did in this way:

  1. add to index.html in next script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>

It is for using CryptoJs which generate hash

  1. I had
API_KEY = 'my public api key'
BASE_URL = "https://gateway.marvel.com:443/v1/public/";
PRIV_KEY = 'my private api key'
  1. Create function for get data from api:
export const getDataFromAPI = async (query) => {
  try {
    let ts = new Date().getTime();
    lethash = CryptoJS.MD5(ts + PRIV_KEY + API_KEY).toString();
    const url = `${BASE_URL}${query}?ts=${ts}&apikey=${API_KEY}&hash=${hash}`;
    const res = await fetch(url);
    const data = await res.json();
    console.log(data);
    return data;
  } catch (error) {
    console.log(error);
  }
}

query can be 'characters', 'comics', 'creators', 'events', 'series', 'stories'. Depends on endpoint

Iryna
  • 1
  • 1