【问题标题】:Angular 6 HTTP Client Post - Bad requestAngular 6 HTTP 客户端发布 - 错误请求
【发布时间】:2021-02-21 14:48:41
【问题描述】:

我有以下问题。 我有一个 API 所在的服务器,我将请求发送到注册端点,但作为响应,我收到 400 Bad Request 错误,说明必须填写姓名、姓氏、电子邮件等。问题是他们被填满了。我不再想念想法了。我的代码:

import {Component} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    title = 'Brak tytułu';

    constructor(private http: HttpClient) {
    }

    registerUser() {
        const config = {headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')};
        const user: User = {
            name: 'Pawel',
            surname: 'Tester',
            email: 'tester@wp.pl',
            password: 'loremipsum12',
            password_confirm: 'loremipsum12',
            event_id: 1,
        };

        this.http.post('https://myapiserver', user, config).subscribe((res) => {
                console.log(res);
                console.log(user);
            },
            error => {
                console.log(error);
                console.log(user);
            });
    }
}

interface User {
    name: string;
    surname: string;
    email: string;
    password: string;
    password_confirm: string;
    event_id: number;
}

这段代码运行良好,但他是 angularJS

    // User create
$scope.createUser = function()
{
    var create_req = $rootScope.reqDefaults;
        create_req.method = 'POST';
        create_req.url = $rootScope.api+'/admin/user';
        create_req.data = $httpParamSerializerJQLike($scope.current);
        create_req.transformRequest = angular.identity;

    // Users list
    $http(create_req)
        .then(function(response){
            $location.path('/users');
            $.notify({
                title: '<strong>Użytkownik utworzony.</strong>',
                message: $scope.current.name+' '+$scope.current.surname+' (ID: '+response.data.id+')'
            },{
                type: 'success'
            });
            return true;
        }, function(response){
            $rootScope.rspError(response.data);
            return false;
        });
};

如果我从 Postman 向注册端点发送请求,一切正常,我的用户注册正确:(我将内容类型设置为 application/x-www-form-urlencoded。

【问题讨论】:

  • 您使用的是哪个网络服务器?
  • 你好,服务器是如何实现的?使用浏览器的开发工具,您应该能够检查消息的真实内容。你能仔细检查一下吗?
  • 我在 VPS 上使用 Symfony 3 的真实 API

标签: angular


【解决方案1】:

来自AngularHttpClient 实际上非常聪明,可以确定您的请求应该包含哪种类型的内容。通过查看this 行的源代码

if (this.body instanceof HttpParams) {
  return 'application/x-www-form-urlencoded;charset=UTF-8';
}

如果您将正文设置为HttpParams,您将看到它会为您设置所需的标题。因此,您的问题的解决方案应该是:

const body = new HttpParams()
  .set('name', 'foo')
  .set('surname', 'bar')

this.http.post('https://myapiserver', body).subscribe(...);

【讨论】:

    【解决方案2】:

    不要设置内容头,默认情况下会将它们设置为 JSON,或者像这样将它们设置为 JSON:application/json

    如果您的 API 需要表单编码的有效负载,那么您应该像原来一样保留标头,但修改请求以发送表单编码的数据,如下所示:

      const body = new HttpParams()
        .set('name', 'Pawel')
        .set('surname', 'Tester');
    
      this.http.post('https://myapiserver',
        body.toString(),
        config
      );
    

    【讨论】:

    • 第一次设置在application/json上,第二次完全没有设置,可惜还是有不好的请求。
    • 您的 API 是否需要 JSON 正文?如果没有,请查看我编辑的答案
    【解决方案3】:

    这对我有用

    const config = new HttpHeaders().set('Content-Type', 'application/json')
                                    .set('Accept', 'application/json')
    
    this.http.post('https://myapiserver', JSON.stringify(user), 
                   { headers: config }).subscrib.....
    

    希望对你有帮助

    编辑:使用新的 HttpClientModule

    const formData = new FormData();
    
    // append your data
    formData.append('myKey1', 'some value 1');
    formData.append('myKey1', 'some value 2');
    formData.append('myKey3', true);
    
    this.httpClient.post('https://myapiserver', formData);
    

    不要设置 Content-Type 标头,Angular 会为您解决这个问题! 来源:How to force Angular2 to POST using x-www-form-urlencoded

    【讨论】:

    • 我用的是一个接受JSON的asp.net core webapi,不知道是不是你的情况
    • 错误请求 :( 见我的问题
    • 这就是我添加 JSON.stringify(user) 的原因,但如果您的端点接受 JSON,这将起作用。我看到了一个 Symfony (andrewadcock.com/a-simple-restful-api-tutorial-with-symfony-3) 的示例,它需要 url 中的参数。我不知道你是什么情况。先试试邮递员看看有什么用。
    • 我将端点添加到邮递员,将内容类型设置为 application/x-www-form-urlencoded,发送请求。状态码200,我的用户注册正确。
    【解决方案4】:

    我在这里看到的两个主要问题: HttpHeaders 缺少授权:

    const config = {headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
    HttpHeaders().set('Authorization': 'Basic ' + credentials);
    HttpHeaders().set('Accept':'*/*')
    };
    

    凭证可以是:const credentials = btoa("angularUser"+":"+"password"); 必须在要验证的后端的 CORS 中定义。

    另外一个就是body,应该定义如下:

    let user = new URLSearchParams();
    
    user.set('param1', 'value1');
    user.set('param2', 'value2');
    

    ...

    如果不起作用,请尝试将Content-type from 'application/x-www-form-urlencoded' 更改为'application/json'。 这至少对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      相关资源
      最近更新 更多