首页 > 解决方案 > 发出请求后获得了错误的 request.body(值和名称放错了位置)

问题描述

几个月以来,我一直是编码初学者,但遇到了一个我无法解决的问题:

在我的角度应用程序中,我正在发出一个帖子请求(followUser):

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import {Observable} from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class UsersService {

  constructor(private http : HttpClient) { }


  getAllUsers() : Observable<any> {
    return this.http.get('http://localhost:8080/chatApp/users')
  }
  followUser(userFollowed) : Observable<any> {
  console.log(userFollowed);
  return this.http.post('http://localhost:8080/chatApp/follow-user', {
    userFollowed
  });
  }
}

userFollowed 是一个包含 ID 的对象(console.log 返回 5da24df09a3e662fd437d21b)

然而,当我在我的节点后端收到这个对象时,我只是 console.log 像这样:

followUser (req,res) {
   console.log(req.body);}

我从控制台获得这个:

{ '{"userFollowed":"5da24df09a3e662fd437d21b"}': '' }

同样如您所见,这是一团糟,我不知道如何解决(我无法访问我的 userFollowed 值)

编辑:关注的用户是一个简单的对象,正如我在前面的 console.log(request.body) 中的评论部分所说,我获得了我期望的值:

{userFollowed:"5da24df09a3e662fd437d21b"} 当我在我的后端得到它并且我 console.log(request.body) 我得到{ '{"userFollowed":"5da24df09a3e662fd437d21b"}': '' }

编辑 2:我将涉及 userFollowed 的整个代码放在下面:

<div class = "container" style = "margin-top : 30px">
  <div  class = "row"> 
    <div class = "col s12 m4 13">
      
     </div>
  
     <div class = "col s12 m8 19">
       <div class = "rox">
         <div class = "col s 12 m6  14 cardDiv" *ngFor = "let user of users">
          <div class = "card">
            <a>
              <div class = "card-image imgDiv">
                <img  class = "imgCircle responsive-img" src = "http://placehold.it/100x100">
              </div>
            </a>
            <div class = "card-action">
              <h3 class = "card-title">
                  {{user.username}}
                  ici sont les username normalement :/
              </h3>
              <p>country</p>

              <button class = "btn" (click)= "followUser(user)">follow</button>
               <!--" need to add this instead of /chat solo-->
              <a class = "secondary-content" [routerLink] = "['/chat', user.username]">
                <i clas = "material-icons">chat</i>
              </a>
            </div>
          </div>
         </div>
       </div>
     </div>
  </div>

以及与之链接的 TS 文件:

import { Component, OnInit } from '@angular/core';
import {UsersService} from './../../services/users.service';
import _ from 'lodash';
import {AuthenticationService } from '../../services/authentication.service';

@Component({
  selector: 'app-people',
  templateUrl: './people.component.html',
  styleUrls: ['./people.component.scss'],
})
export class PeopleComponent implements OnInit {
users = [];
loggedInUser : any;
  constructor( private usersService : UsersService, private authService : AuthenticationService) { }

  ngOnInit() {
    this.loggedInUser = this.authService.userData;
    this.getUsers();
    }
  
getUsers () {
  this.usersService.getAllUsers().subscribe (data =>{
    _.remove(data.result, {username : this.loggedInUser.username});
    this.users=data.result;
    console.log(this.users);
});
}
followUser(user) {
  console.log(user._id);
this.usersService.followUser(user._id).subscribe(data=> {
  console.log(data);
})

}
}

编辑 3:我的节点如下所示:

const express = require('express');
const bodyParser = require('body-parser');
const logger = require('morgan');
const methodOverride = require('method-override')
const cors = require('cors');
const mysql = require('mysql');
// Token handling : 
const jwt = require('jsonwebtoken');
const config = require('./config/config');
//disk storage :
const multer = require('multer');
// password hashing : 
const bcrypt = require('bcrypt');
const saltRounds = 10;
const dateTime = require ('date-time');
const nodemailer = require('nodemailer');
// ---------------------------------------
const connection = mysql.createConnection({          // a placer dans une variable environnementale

});


var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));

// TUTO PATRICK MONGODB

const mongoose = require('mongoose');
const dbConfig = require ('./config/secret');
const message = require ('./routes/messageRoutes');
const auth = require ('./routes/authRoutes');
const users = require('./routes/userRoutes');
const friends = require ('./routes/friendsRoutes');

mongoose.Promise = global.Promise;
mongoose.connect(
    dbConfig.url,
    { useNewUrlParser : true}
);
app.use ('/chatApp', auth);
app.use('/chatApp', message );
app.use('/chatApp', users);
app.use('/chatApp', friends);

app.use(express.json());

然后路线:

const express = require('express');
const router = express.Router();
const friendCtrl = require('../controllers/friends.js');
const authHelper = require("../helpers/authHelper");

router.post('/follow-user', authHelper.ProtectedRoutes, friendCtrl.followUser);
module.exports = router;

然后执行的代码

var User = require('../Models/userModels');
module.exports = {
    followUser (req,res) {
        console.log(req.body);};

标签: javascriptangularrxjs

解决方案


因此,感谢那些试图提供帮助的人,发生的事情是我的 HTTP 拦截器设置了两次标头(application/json 和 application/x-www-form-urlencoded),导致 bodyparserJson 和 bodyparserUrlencoded 都解析我的请求,这确实导致了奇怪的结果。错误的代码拦截器:

import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, from } from 'rxjs';
import { ToastController } from '@ionic/angular';
import {Storage} from '@ionic/storage';
import { switchMap } from 'rxjs/operators';
import {AuthenticationService} from './../services/authentication.service';
@Injectable({
  providedIn: 'root'
})
export class TokenInterceptorService implements HttpInterceptor {



  constructor(public toastController: ToastController, private storage : Storage) {}


  intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
    const TOKEN_KEY ='ACCES_TOKEN';    
    console.log("requete avant",request.body);
     return from(this.storage.get(TOKEN_KEY))
          .pipe(
            switchMap(token => {
              if (token){
              console.log("InterceptedHTTPRequest")
               const headers = request.headers
                        .set('x-access-token', token)
                        .append('Content-Type', 'application/x-www-form-urlencoded'); // application/json instead of application/x-www..., had to use the 2nd one because of CORS blocked in chrome
               const requestClone = request.clone({
                 headers 
                });
                console.log("request interceptée et clonée");
                console.log("request apres",requestClone.body);
              return next.handle(requestClone);
              }
              else {
                return next.handle(request);
              }

              }),
            );

  }
}


更正的拦截器:

import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, from } from 'rxjs';
import { ToastController } from '@ionic/angular';
import {Storage} from '@ionic/storage';
import { switchMap } from 'rxjs/operators';
import {AuthenticationService} from './../services/authentication.service';
@Injectable({
  providedIn: 'root'
})
export class TokenInterceptorService implements HttpInterceptor {



  constructor(public toastController: ToastController, private storage : Storage) {}


  intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
    const TOKEN_KEY ='ACCES_TOKEN';    
    console.log("requete avant",request.body);
     return from(this.storage.get(TOKEN_KEY))
          .pipe(
            switchMap(token => {
              if (token){
              console.log("InterceptedHTTPRequest")
               const headers = request.headers
                        .append('x-access-token', token)
               const requestClone = request.clone({
                 headers 
                });
                console.log("request interceptée et clonée");
                console.log("request apres",requestClone.body);
              return next.handle(requestClone);
              }
              else {
                return next.handle(request);
              }

              }),
            );

  }
}









推荐阅读