web-dev-qa-db-fra.com

Impossible d'envoyer une demande de publication lorsque le "Content-Type" est défini sur "application / json"

Je travaille sur une application React et j'utilise fetch pour envoyer une demande. J'ai récemment créé un formulaire d'inscription et maintenant je l'intègre à son API. Auparavant, l'API acceptait les URL codées données et tout fonctionnait bien. mais maintenant que l'exigence a changé et que l'API accepte les données en JSON, j'ai dû changer l'en-tête de type de contenu de 'application/x-www-form-urlencoded' en 'application/json' Mais j'obtiens l'erreur suivante:

L'API de récupération ne peut pas se charger http://local.moberries.com/api/v1/candidate . La réponse à la demande de contrôle en amont ne passe pas la vérification du contrôle d'accès: aucun en-tête "Access-Control-Allow-Origin" n'est présent sur la ressource demandée. L'origine ' http: // localhost: 30 ' n'est donc pas autorisée à accéder. Si une réponse opaque répond à vos besoins, définissez le mode de la demande sur "no-cors" pour récupérer la ressource avec CORS désactivé.

J'ai même défini le 'Access-Control-Allow-Headers' dans l'API mais cela ne fonctionne toujours pas. Voici le code pertinent pour le côté client:

sendFormData() {
    let {user} = this.props;

    var formData = {
      first_name: ReactDOM.findDOMNode(this.refs.firstName).value,
      last_name: ReactDOM.findDOMNode(this.refs.lastName).value,
      city: ReactDOM.findDOMNode(this.refs.currentCity).value,
      country: ReactDOM.findDOMNode(this.refs.currentCountry).value,
      is_willing_to_relocate: user.selectedOption,
      cities: relocateTo,
      professions: opportunity,
      skills: skills,
      languages: language,
      min_gross_salary: minSal,
      max_gross_salary: maxSal,
      email: ReactDOM.findDOMNode(this.refs.email).value,
      password: ReactDOM.findDOMNode(this.refs.password).value
    };

    var request = new Request('http://local.moberries.com/api/v1/candidate', {
      method: 'POST',
      mode: 'cors',
      headers: new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      })
    });

    var requestBody = JSON.stringify(formData);

    console.log(requestBody);

    fetch(request, {body: requestBody})
      .then(
        function (response) {
          if (response.status == 200 || response.status == 201) {
            return response.json();
          } else {
            console.log('Failure!', response.status);
          }
        }).then(function (json) {

      var responseBody = json;

      console.log(typeof responseBody, responseBody);
    });

  }

Et voici le code API pertinent:

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
            ->header('Access-Control-Allow-Headers: Origin, Content-Type, application/json');
    }
}

Je ne peux vraiment pas comprendre le problème. Tout type d'aide sera apprécié.

10
Arslan Tariq

Il s'avère que CORS n'autorise que certains types de contenu spécifiques.

Les seules valeurs autorisées pour l'en-tête Content-Type sont:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • texte simple

Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Pour définir le type de contenu sur "application/json", j'ai dû définir un en-tête de type de contenu personnalisé dans l'API. Je viens de supprimer le dernier en-tête et d'ajouter celui-ci:

->header('Access-Control-Allow-Headers', 'Content-Type');

et cela fonctionne très bien.

22
Arslan Tariq

Vous violez la ' même politique d'origine '. Un site Web www.example.com peut ne jamais être en mesure de charger des ressources à partir d'un site Web www.example.net autre que lui-même.

Cependant, pendant le développement, il faut parfois être capable de le faire. Pour contourner cela:

  1. soit déplacez votre origine vers http://local.moberries.com ,
  2. ou déplacez l'API (à laquelle vous accédez) vers votre hôte local.
  3. En dehors de cela, il existe des moyens de désactiver temporairement les restrictions de ce type dans certains navigateurs (en particulier Chrome), dont les méthodes nécessitent généralement de plus en plus d'efforts dans les mises à jour ultérieures du navigateur. Recherchez sur Google comment activer le partage de ressources d'origine croisée dans votre version du navigateur.
  4. Ou, comme le suggère l'erreur Prompt, introduisez un en-tête permettant aux demandes d'être reçues de non-origines. Plus d'informations sont dans la documentation pour Access Control CORS
0
Abdul Wasae