2017-10-20 44 views
1

J'ai un problème ennuyeux. J'essaie de créer un site web simple. Ce site utilise une API que je construis en utilisant nodejs et express. En développant l'API, j'ai constamment vérifié la fonctionnalité avec Postman. Tout a fonctionné et fonctionne toujours bien (en utilisant Postman).Express ne pas acheminer certaines requêtes jQuery

Maintenant, j'ai commencé à travailler sur mon site Web. Les premiers GET et POST fonctionnaient bien. (J'ai essayé quelques librairies ajax légères, aucune ne fonctionnait, seulement jQuery semble fonctionner pour moi)

Maintenant j'essaye de mettre à jour un article utilisant le verbe PUT. Encore une fois la mise à jour fonctionne très bien en utilisant le facteur. Mais essayer d'utiliser jQuery ne déclenche pas le bon chemin dans express. Pour vérifier cela, j'ai ajouté un simple console.log si express utilisé le dernier middleware qui renvoie également un 404 statuscode et un console.log dans la fonction qui gère le PUT. Chaque fois que j'utilise jQuery pour mettre à jour un élément, il va à 404. Si j'utilise Postman, je vois le message de la fonction PUT.

Mon APIController (NodeJS avec Express):

let express = require('express'); 
//let path = require('path'); 
let bodyParser = require('body-parser'); 
let mongoose = require('mongoose'); 
mongoose.connect('mongodb://localhost:27017/test', { useMongoClient: true }); 
require('./Models/InitModels'); 

let app = express(); 
app.use(function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
    next(); 
}); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true})); 

let routes = require('./Routes/APIRoutes'); 
routes(app); 

// catch 404 and forward to error handler 
app.use(function(req, res, next) { 
    res.status(404); 
    console.log("Returning 404 to request"); 
}); 

app.set('port', 2017); 
app.listen(2017); 
console.log("Starting API Controller"); 

Routes API (seulement Karte est important ici):

module.exports = function(app) { 
let benutzer = require('../Controller/BenutzerController'); 
let gruppe = require('../Controller/GruppenController'); 
let zugriffslog = require('../Controller/ZugriffsLogController'); 
let karten = require('../Controller/KartenController'); 
let zugriffszeit = require('../Controller/ZugriffsZeitenController'); 

app.route('/karten') 
    .put(karten.put) 
    .post(karten.post) 
    .delete(karten.delete); 

Et puis le KartenController:

exports.post = (req, res) => { 
    if (req.body.search) { 
     Karte.find(req.body.search) 
      .populate('benutzer').populate('gruppen') 
      .exec((err, karten) => { 
       res.json(karten) 
      }); 
    } else if(req.body.karte) { 
     if (this.createdKarte !== null) { 
      res.json({"error": {"code": 110}}); // card needs to be scanned 
     } else { 
      let newKarte = new Karte(req.body.karte); 
      newKarte.save(); 
      //this.createdKartenDatum = new Date(); 
      res.json(newKarte); 

      // Add Karte To User 
      //Benutzer.findOneAndUpdate({_id: newKarte.benutzer}, {$push: {karten: newKarte._id}}); 
      //Benutzer.findOneAndUpdate({_id: newKarte.benutzer}, {$pull: {karten: newKarten._id}}); 

      this.kartenCreateDatum = new Date(); 
      this.createdKarte = newKarte; 
      this.kartenScannPending = true; 

      // Abort after some time 
      setTimeout(scannTimeExpired, timeTillCreationExpires); 
     } 
    } else if(req.body.status) { 
     if (this.kartenScannPending) { 
      res.json({"status": {"code": 300}}); // waiting for card to be scanned 
     } else if (this.kartenScannFehler !== null) { 
      res.json(this.kartenScannFehler); // fehler aufgetreten 
      this.kartenScannFehler = null; // aufräumen 
     } else if (this.kartenScannErfolgreich) { 
      res.json({"status": {"code": 500, "date": this.kartenCreateDatum}}); // karte gescanned 
      this.kartenScannErfolgreich = false; 
     } else { 
      res.json({"status": {"code": 404}}); // no card needs to be scanned 
     } 
    } else { 
     res.json({ "error": "U SUCK" }); 
    } 
}; 

exports.put = (req, res) => { 
    console.log("Trying to put a Card)"); 
    if (req.body.karte) { 
     if (req.body.karte.name && req.body.karte._id) { 
      Karte.findOneAndUpdate({_id: req.body.karte._id}, {$set: req.body.karte}, {new: true},(err, karte) => res.json(karte)); 
     } else { 
      res.json({"error": {"code": 120}}); 
     } 
    } else { 
     res.json({"error": {"code": 120}}); 
    } 
}; 

Mon Javascript ressemble à ceci:

$.ajax({ 
    type: "POST", 
    context: this, 
    url: "http://localhost:2017/karten", 
    data: { 
     search: { 
      benutzer: { 
       _id: this.benutzer._id 
      } 
     } 
    }, 
    async: true, 
    success: function (data) { 
     console.log(data); 
    }, 
    dataType: "json" 
}); 

// Zugriffszeiten abfragen 
$.ajax({ 
    type: "PUT", 
    context: this, 
    url: "http://localhost:2017/karten", 
    data: { 
     karte: { 
      _id: this.karte._id, 
      name: "PLS WORK !!!" 
     } 
    }, 
    async: true, 
    success: function (data) { 
     console.log(data); 
    }, 
    dataType: "json" 
}); 

Le résultat:

premier:

travaille et me donner un tableau de deux cartes

seconde:

me faire un TRE :: EMPTY_RESPONSE (en raison de la 404) et les sorties de la console de nodejs "retour 404 pour demander"

Essayer la même chose avec Postman, tout fonctionne et les cartes sont mises à jour

J'espère vraiment que quelqu'un peut m'aider avec cela, car je travaille sur ce temps depuis longtemps et ne peux pas sembler voir mon erreur.

Merci d'avoir lu tout :)

+0

Avez-vous vérifié les paramètres d'autorisation? La requête Ajax ne peut pas simplement passer par différents ports. –

+1

Je me demande s'il s'agit d'une demande d'origine croisée du navigateur. Si c'est le cas, vous devrez prendre en charge la requête OPTIONS sur votre serveur afin que la demande d'origine croisée soit autorisée pour une demande PUT. Un simple POST ou GET fonctionnera uniquement avec l'en-tête CORS que vous utilisez déjà, mais un PUT nécessite probablement un gestionnaire pour une requête OPTIONS. – jfriend00

+1

Si vous ouvrez l'onglet réseau dans votre débogueur de navigateur et observez ce que le navigateur fait lorsque vous effectuez ces appels ajax, vous pouvez probablement voir la requête OPTIONS envoyée et retournée avec un 404. – jfriend00

Répondre

1

Merci à jfriend00, je trouve la solution au problème. Je n'ai pas respecté les options-demande correctement. je devais ajouter quelques lignes de code à mon APIController:

app.use(function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE"); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 

    // The routes wont fire on that options-request, so it sends a 404 response and thus the ajax request times out 
    //intercepts OPTIONS method 
    if ('OPTIONS' === req.method) { 
     //respond with 200 
     console.log("Received options request"); 
     res.send(200); 
    } 
    else { 
     //move on 
     next(); 
    } 
}); 

Maintenant, tout fonctionne comme prévu.