Угловой для узла + Express.js http.post () остановлен: состояние 204 нет содержимого.Предполагаемые варианты предполетной проверки CORS - PullRequest
0 голосов
/ 03 января 2019

Я использую клиентскую версию ionic со стороны сервера node.js + express.js. В настоящее время тестирую на моем локальном компьютере.

Я могу сделать POST-запрос через почтальона, однако я не смог сделать это через ionic.

Исследование

Я потратил почти 1 день, чтобы исследовать это. Но я не мог найти способ решить это. Более того, нет ошибок ни на клиенте, ни на стороне сервера, поэтому мне сложно исследовать это.

Из того, что я вижу, я подозреваю, что ошибка происходит из настроек PREFLIGHT OPTIONS. Я должен установить его где-нибудь в моем узле + экспресс. Я использую плагин cors https://www.npmjs.com/package/cors и использую настройки, чтобы разрешить опции PREFLIGHT, однако он все равно не работает.

Я посмотрел проверку сети Chrome, вот что у меня есть: Network Inspection (1) Network Inspection (2)

И это то, что выглядит в консоли. Console Inspection

Мой код на стороне клиента (Ionic)

postAPI() {
  return new Promise ((resolve,reject)=>{
    this.http.post("http://localhost:8080/api/status/", {
      "body" : "This is the body post"
    }, httpOptions).subscribe((val) => {
      console.log("POST call successful value returned in body", val);
      resolve();
    }, error => {
      console.log("POST call in error", error);
      reject();
    }, () => {
      console.log("The POST observable is now completed.");
    })
  })
}

Мой код на стороне сервера (Node + Express)

Здесь я использую настройки CORS OPTIONS, чтобы разрешить все запросы OPTIONS. Я устанавливаю его в server.js, а сам маршрут в status.js.

server.js

const express    = require('express');           // call express
const app        = express();                    // define our app using express
var cors         = require('cors');               // setup CORS so can be called by ionic local app
const port       = process.env.PORT || 8080;      // set our port

// ALLOW CORS
app.use(cors());
// SET CORS for PREFLIGHT OPTIONS
app.options('*', cors());

// Libraries
const bodyParser = require('body-parser');

const admin   = require('firebase-admin');
const serviceAccount = require('./serviceAccountKey.json');

// Json
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// Firebase Configs
//firebase admin sdk for Firestore
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://menuu-sm-dev.firebaseio.com"
});

var afs = admin.firestore();
var db = afs;
app.set("afs", afs);
var db = admin.firestore();
const settings = {timestampsInSnapshots: true};
db.settings(settings);

app.set("db", db);

// ROUTES
app.use('/api',require('./routers/api/api'));
app.use('/',require('./routers/home'));

// START
app.listen(port);
console.log('Server is served on port ' + port);

api.js

// SETUP
const express = require('express'),
  router = express.Router();
const url = require("url");
const path = require("path");
///const sanitizer = require("sanitize")();

// ROUTES (/api/)
router.use('/user',require('./user'));
router.use('/status',require('./status'));
router.use('/timeline',require('./timeline'));
router.use('/photo',require('./photo'));
router.use('/like',require('./like'));
router.use('/comment',require('./comment'));
router.use('/checkin',require('./checkin'));
router.use('/promotion',require('./promotion'));

// OTHERS
module.exports = router;

status.js

// SETUP
const express = require('express'),
  router = express.Router();
const url = require("url");
const path = require("path");
const Timeline = require("../../models/Timeline");
const Post = require("../../models/Post");
///const sanitizer = require("sanitize")();

// ROUTES

// ===============================================================
// /status/
var statusRoute = router.route('');

// Create
statusRoute.post((req, res) => {
  let query = url.parse(req.url,true).query;
  let userKey = query.userkey;
  let statusKey = query.statuskey; // ga dipake
  let reqBody = req.body;
  let db = req.app.get('db');
  // ! remember to do sanitizing here later on

  if (typeof userKey != 'undefined'){
    // Create New Status
    let newStatusRef = db.collection('status/'+userKey+'/status').doc();
    newStatusRef.set(reqBody);

    // Fan-Out
    let docId = newStatusRef.id; // get pushed id
    //let docId = "1";

    // Insert request body to models
    var post = new Post();
    var timeline = new Timeline();
    Object.entries(reqBody).forEach( ([key, value]) => {
        timeline.set(key,value);
        post.set(key,value);
      }
    );

    // Specify operations to be done
    var batch = db.batch();
    let newPostRef = db.collection('posts/'+userKey+'/posts').doc(docId);
    batch.set(newPostRef, post.data);
    console.log("b" + batch);


    // Timeline & Commit
    getFollowers(userKey, db)
      .catch((error) => {
        console.error("Error writing document: ", error)
      })
      .then((followers) => {
        // ATTENTION!!
        // if followers > 9, batch write supposedly wont work because max limit of batch write is 10
        if (followers.length!=0){
          followers.forEach((f) => {
            let newTimelineRef = db.collection('timeline/'+String(f)+'/timeline').doc(docId);
            console.log(typeof batch);
            console.log("a" + batch);
            batch.set(newTimelineRef, timeline.data);
          });
        }

        // Commit changes
        batch.commit()
          .then(() => {
            console.log("POST Request");
            res.json({"Action":"CREATE","Status":"Successful", "User key":userKey, "Post Key": docId, "followers":followers});
          })
          .catch((error) => {
            console.error("Error writing document: ", error)
          })
      });
  }
});

Не могли бы вы помочь мне найти причину этой проблемы. Спасибо!

1 Ответ

0 голосов
/ 03 января 2019

Замените app.use ('cors') следующим кодом:

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", '*');
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
  );
  if (req.method === 'OPTIONS') {
      res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
      return res.status(200).json({});
  }
  next();
});
...