Как обеспечить функцию обратного вызова в API поиска iTunes - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь найти способ предоставить функцию обратного вызова для правильного использования API поиска в iTunes Store .

Я пытаюсь добиться этого поведения:

const getiTunes = fetch(`https://itunes.apple.com/search?term=${search}&media=movie&limit=200`)
  .then(results => results.json())
  .then(results => {
    if (results.errorMessage) throw Error(results.errorMessage)
    else setResults(results)
  })
  .catch(error => {
    //handle error
  })

и до сих пор у меня есть это:

const getiTunes = results =>  {
  if (results.errorMessage) throw Error(results.errorMessage)
  else setITunes(results)
}

const script = document.createElement("script")
script.src = `https://itunes.apple.com/search?term=${search}&media=movie&limit=200&callback=getiTunes`
script.async = true
document.body.appendChild(script)

Я получаю следующую ошибку:

Uncaught ReferenceError: getiTunes is not defined

Я также пробовал &callback="getiTunes" и &callback=${getiTunes}, и они также терпят неудачу.

Эти функции вызываются в ловушке useEffect в React. Есть ли конкретный c способ получения имени функции?


В стороне

И если я пытаюсь не предоставлять функцию обратного вызова, она будет работать, только если поиск является новым поиском (ie Я не искал этот термин раньше). Однако, если у меня есть (скажем, на производственном URL или локально), произойдет ошибка со следующим:

Access to fetch at 'https://itunes.apple.com/search?term=spiderman&media=movie&limit=200' from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value "--it has the last URL I used to search for this successfully--"...

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

Я смог заставить это работать, добавив свой скрипт для обработки ответа на документ.

const loadItunes = document.createElement("script")
loadItunes.src = `https://itunes.apple.com/search?term=${search}&media=movie&limit=200&callback=getiTunes`
loadItunes.async = true

const handleResults = document.createElement("script")

handleResults.type = "text/javascript"
handleResults.text = "function getiTunes(response) { //function code };"

document.body.appendChild(loadItunes)
document.body.appendChild(handleResults)

Обновленный ответ

Я нашел лучшее решение с помощью этой песочницы кода . Он прекрасно решает эту проблему, создавая функцию, которая затем передает ответ на функцию обратного вызова.

export const fetchJSONP = (url, callback) => {
  var callbackName = "jsonp_callback_" + Math.round(100000 * Math.random())
  window[callbackName] = function (data) {
    delete window[callbackName]
    document.body.removeChild(script)
    callback(data)
  }

  var script = document.createElement("script")
  script.src = url + (url.indexOf("?") >= 0 ? "&" : "?") + "callback=" + callbackName
  document.body.appendChild(script)
}

Затем я использую ее следующим образом:

const handleResponse = response => {
  //do stuff with response
}
fetchJSONP("https://itunes.apple.com/search?term=spiderman&media=movie&limit=200", handleResponse)
0 голосов
/ 25 апреля 2020

Вы пытаетесь использовать метод JSONP (JSON with Padding). Нам просто нужен внешний скрипт и функция. Внешний веб-сайт предоставляет функцию обратного вызова для вашего метода.

Таким образом, он отправляет все данные в параметре функции.

, по ошибке вы добавили } к URL-адресу вашего скрипта

script.src = `https://itunes.apple.com/search?term=${search}&media=movie&limit=200&callback=getiTunes}`

Например, код:

const getiTunes=results=>{
if (results.errorMessage) throw new 
Error(results.errorMessage)
  else setITunes(results)
};
const script = document.createElement("script")
script.src = `https://itunes.apple.com/search?term=bat&media=movie&limit=200&callback=getiTunes`
script.async = true
document.body.appendChild(script);
// returns getiTunes(...someData)
...