Apollo-link-rest: "Les en-têtes ne sont pas définis" se produit lors de l'utilisation d'apollo-link-rest dans le mini programme weixin

Créé le 16 juil. 2019  ·  25Commentaires  ·  Source: apollographql/apollo-link-rest

  • [x] a-reproduction

Lorsque nous essayons d'utiliser apollo-link-rest dans le mini programme weixin, nous avons rencontré un problème qui a généré une erreur comme ci-dessous:

 Headers is not defined 
 ReferenceError: Headers is not defined

Comme j'ai trouvé le code source dans RestLink.ts, il essaie de trouver les en-têtes, mais absolument , il n'y a pas d'en-têtes sous l'environnement weixin, alors quelqu'un peut-il aider à fournir un piratage ou des solutions pour résoudre ce problème? Merci beaucoup si vous pouviez aider, merci.

help wanted 🛠 question❔

Commentaire le plus utile

Voici ce qui a fonctionné pour moi:

import clientFetch from 'unfetch';
import serverFetch, { Headers as ServerHeaders } from 'node-fetch';

const client = typeof document !== 'undefined';
global.Headers = client ? global.Headers : ServerHeaders;
const customFetch = client ? clientFetch : serverFetch;

const acmeLink = new JsonApiLink({
  …
  credentials: 'same-origin',
  customFetch,
});

Tous les 25 commentaires

Salut @ Janice1114 , je ne suis pas familier avec weixin, mais peut-être que vous pouvez utiliser un Headers Polyfill?

Souvent, si les en-têtes ne sont pas disponibles, Fetch sera également indisponible. Donc, un polyfill qui pourrait fonctionner pour les deux est celui-ci: https://github.com/bitinn/node-fetch

Salut @fbartho , merci pour votre réponse rapide. J'ai essayé d'utiliser le polyfill pour activer les en-têtes de récupération, mais j'obtiens toujours les erreurs.

Et j'ai trouvé que sous weixin, il utilise wx.request pour la récupération, qui ne prend pas en charge la variable liée à la fenêtre, donc j'ai peur que le polyfill ne fonctionne pas.

Et puis-je savoir qu'il y aurait un piratage ou des implémentations pour aider à ignorer la boucle des en-têtes dans le code source de apollo-link-rest? Ou pourriez-vous s'il vous plaît donner des options personnalisées en fonction de différents scénarios?

Vous pouvez utiliser le paramètre customFetch pour ApolloLinkRest afin de fournir une fonction wrapper, cette fonction wrapper peut prendre les en-têtes basés sur la fenêtre du Polyfill et l'aplatir en un objet traditionnel Hash.

Quelque chose comme ce qui suit (non testé, écrit dans mon navigateur):

function customFetch(url, options) {
   const headers = options.headers.entries().reduce((accumulator, h) => { accumulator[h[0]] = h[1];  return accumulator;}, {})
   return fetch(url, {…options, headers});
}
// Elsewhere: new RestLink({ customFetch, ...

Merci beaucoup pour votre aimable réponse, je vais essayer d'utiliser ce polyfill dans le développement de weixin.

Et en lisant le code source dans RestLink.ts, il essaiera d'accéder aux en-têtes, qui ne sont pas disponibles dans weixin. Il pourrait affecter les variables dans global .

Je me demande donc si des paramètres personnalisés ou remplacés pourraient être appliqués pendant le processus du constructeur RestLink?

Meilleures salutations pour vos si merveilleux conseils.

Salut @fbartho , pour résoudre ce problème dans weixin et le navigateur spécial associé, j'ai créé un PR comme ci-dessous:
Correction du problème des en-têtes

Pourriez-vous s'il vous plaît aider et vérifier si le code PR est disponible pour fusionner dans le maître?
J'apprécie beaucoup et merci beaucoup si cela pouvait aider.

J'ai le même problème dans "next": "^9.0.3"

J'ai aussi ce problème avec la prochaine version ^8.1.0 . Pour mon API graphique, j'utilise isomorphic-unfetch , version ^3.0.0 pour polyfill comme ceci:

import fetch from 'isomorphic-unfetch'
const graphLink = createHttpLink({ uri, fetch })

Mais utiliser le même package pour polyfill avec le lien rest ne fonctionnait pas:

const restLink = new RestLink({
  uri,
  customFetch: fetch,
})

J'ai également essayé node-fetch utilisant votre méthode customFetch:

import fetch from 'node-fetch'

function customFetch(url, options) {
  const headers = options.headers.entries().reduce((accumulator, h) => {
    accumulator[h[0]] = h[1]
    return accumulator
  }, {})
  return fetch(url, { ...options, headers })
}

const restLink = new RestLink({
  uri: CONTENTFUL_CONTENT_DELIVERY_API,
  customFetch,
})

Dans les deux cas, j'ai obtenu ReferenceError: Headers is not defined lors de l'exécution suivante en mode dev.

J'adore l'idée ici, j'adorerais si vous pouviez fournir des indications sur la façon de l'implémenter dans les environnements de serveur. Merci!

Vous pouvez polyfill l'API Headers tout en utilisant votre propre API customFetch!

Faites-moi savoir si vous souhaitez un exemple de code là-bas, mais je suis convaincu que cela est faisable sans trop de tracas. Je ne suis pas devant mon ordinateur pour l'instant.

@fbartho Un exemple de code serait génial lorsque vous en avez l'occasion! J'ai essayé, mais je n'ai pas réussi. Merci!

import * as Polyfillheaders from 'fetch-headers'
import fetch from 'isomorphic-unfetch'

// hook in the Headers polyfill for your environment!
global.Headers = global.Headers || Polyfillheaders;

function customFetch(url, options) {
  const headers = options.headers.entries().reduce((accumulator, h) => {
    accumulator[h[0]] = h[1]
    return accumulator
  }, {})
  return fetch(url, { ...options, headers })
}

const restLink = new RestLink({
  uri: CONTENTFUL_CONTENT_DELIVERY_API,
  customFetch,
})

Quelque chose comme ce qui précède pourrait faire l'affaire @ 2wheelcoder

Merci! Je ferai un rapport ici après avoir eu la chance de tenter le coup.

@fbartho Salut! Je suis confronté à ce problème sur iOS 9.3.5.J'ai essayé d'importer le polyfill fetch-headers mais ne fonctionne pas.
J'ai trouvé que l'instance d'en-tête de fetch-headers n'a pas la méthode forEach (voir ci-dessous).
image

Y a-t-il d'autres solutions?

@fbartho Salut! Je suis confronté à ce problème sur iOS 9.3.5.J'ai essayé d'importer le polyfill fetch-headers mais ne fonctionne pas.
J'ai trouvé que l'instance d'en-tête de fetch-headers n'a pas la méthode forEach (voir ci-dessous).
image

Y a-t-il d'autres solutions?

J'ai résolu ce problème en utilisant le polyfill fetch .

Je vais fermer cela, car je pense que nous pouvons résoudre cela avec un polyfill du côté de l'application, et nous ne voulons pas faire du polyfill une dépendance de ce référentiel.

Je n'ai pas été en mesure de résoudre ce problème avec un polyfill. J'ai essayé isomorphic-fetch, isomorphic-unfetch, fetch-headers, etc. et je me retrouve toujours avec un problème à propos de current.forEach non défini ou TypeError: Right-hand side of 'instanceof' is not an object . De l'aide?

@VinSpee Avez-vous déjà essayé ce polyfill de récupération .

@lintuming oui mais ça ne marche pas sur le serveur.

@VinSpee Peut-être que vous pouvez utiliser ceci , il semble qu'ils aient la méthode forEach .
image
J'espère que ce travail.

@lintuming merci d'avoir essayé de vous aider. Avec celui-là, j'obtiens:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

semble être un enchevêtrement de problèmes 🤣

@VinSpee Désolé, je n'ai aucune idée de pourquoi cela se produit, mais je pense que cela pourrait aider:
https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client

Voici ce qui a fonctionné pour moi:

import clientFetch from 'unfetch';
import serverFetch, { Headers as ServerHeaders } from 'node-fetch';

const client = typeof document !== 'undefined';
global.Headers = client ? global.Headers : ServerHeaders;
const customFetch = client ? clientFetch : serverFetch;

const acmeLink = new JsonApiLink({
  …
  credentials: 'same-origin',
  customFetch,
});

@VinSpee Je suis confronté au même problème et j'ai essayé de résoudre ce problème avec votre solution, mais je n'ai pas réussi.
Pouvez-vous s'il vous plaît partager votre code de travail

Merci @VinSpee - c'était exactement ce dont j'avais besoin

J'ai pu résoudre ce problème en utilisant la récupération personnalisée

import fetch from "isomorphic-fetch"

const restLink = new RestLink({
  uri: "https://...",
  customFetch: fetch,
  headers: {
    "Content-Type": "application/json",
  },
})

La solution de @VinSpee a également fonctionné pour moi pour une application Gatsby JS.

Cette page vous a été utile?
0 / 5 - 0 notes