【问题标题】:Angular 8: URL encoded form POSTAngular 8:URL 编码形式 POST
【发布时间】:2020-03-02 23:39:40
【问题描述】:

我想将表单数据发布到接受并返回 text/html/xml 的服务器。我正在有效地尝试模拟普通的 URL 编码形式 POST。我的 Angular 8 POST 函数成功发布(200 OK),但服务器无法理解数据,因为它是 JSON 而不是 URL 编码的。

响应和请求标头状态为Content-Type: text/html; Charset=utf-8Accept: text/html, application/xhtml+xml, */*,我已将responseType: "text" 添加到httpClient 选项中。为什么服务器仍然发送 JSON 而不是 URL 编码数据?

// obj2 = output from ngForm
// baseUrl2 = server that sends and receives text/html/xml

public postForm(obj2) {
    return this.httpClient
    .post(this.baseUrl2, obj2, {
        headers: new HttpHeaders({
            "Content-Type": "application/x-www-form-urlencoded",
            Accept: "text/html, application/xhtml+xml, */*"
        }),
        responseType: "text"
    })
    .map(data => data);
}

发送的表单数据:

{"Form data":{"{\"personsNameText\":\"name9\",\"centreEmailAddressText\":\"name9@name.com\",\"centreTelephoneNumberText\":123456789,\"centreNumberText\":\"ab123\",\"centreNameText\":\"ab123\",\"invoiceText\":\"123456789\",\"currencyText\":\"GBP\",\"amountText\":\"100\",\"cardtypeText\":\"Credit card\",\"commentsText\":\"Comments.\",\"declarationText\":true}":""}}

我想要什么:

personsNameText=name9?centreEmailAddressText=name9@name.com?centreTelephoneNumberText=123456789?centreNumberText=ab123?centreNameText=ab123?invoiceText=123456789?currencyText=GBP?amountText=100?cardtypeText=Credit card?commentsText=Comments.?declarationText=true

【问题讨论】:

    标签: javascript angular forms post urlencode


    【解决方案1】:

    所以,这个解决方案为我解决了各种问题:

    1. 使用 Angular 8 的表单和 HttpClient 发布 x-www-form-urlencoded 数据
    2. 更正不需要的编码字符
      • 我的具体问题是唯一的验证字符串包含被转换为 HTML 实体的 & 符号,即 &&
    // userdata.service.ts
    
    public postForm(obj) {
      return this.httpClient
        .post(this.baseUrl2, obj, {
          headers: new HttpHeaders({
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Referer": "http://referer.com" // Replace with your own.
          }),
          responseType: "text"
        })
        .map(data => data)
        .pipe(
          retry(1),
          catchError(this.handleError)
        );
    }
    
    // app.component.ts
    
    PostForm(userdata) {
        // Stringify and convert HTML entity ampersands back to normal ampersands.
        const corrected = JSON.stringify(userdata).replace(/(&)/gm, '&');
        // Convert back to JSON object.
        const corrected2 = JSON.parse(corrected);
        // entries() iterates form key:value pairs, URLSearchParams() is for query strings
        const URLparams = new URLSearchParams(Object.entries(corrected2));
        // Convert to string to post.
        const final = URLparams.toString();
        // Post it
        this.userdataService.postForm(final).subscribe(reponse2 => {
            console.log(reponse2);
        });
    }
    

    URLSearchParams() 是一个突破,正如 Vlad 所建议的,绝对确定要处理的类型。我应该使用Types 来避免混淆。我可能应该使用Angular Interceptors 来处理字符操作。

    【讨论】:

      【解决方案2】:

      我不确定obj2 对象的类型,但我假设它类似于

      interface UserFormData {
        ['Form data']: { [name: string]: value };
      }
      

      在发布之前,您需要将其转换为 FormData。类似的东西:

      const formEncodedObj2 = new FormData();
      const obj2Keys = obj2['Form data'];
      Object.keys(obj2Keys).forEach(key => formEncodedObj2.append(key, obj2Keys[key]));
      

      然后发送formEncodedObj2 对象。

      【讨论】:

      • 谢谢,弗拉德。 obj2 包含:{ "personsNameText": "name9", "centreEmailAddressText": "name9@name.com", "centreTelephoneNumberText": 123456789, "centreNumberText": "ab123", "centreNameText": "ab123", "invoiceText": "123456789", "currencyText": "GBP", "amountText": "100", "cardtypeText": "Credit card", "commentsText": "Comments.", "declarationText": true }
      • 这是弗拉德解决方案后发布的内容:{"Form data":{"100":"","123456789":["",""],"-----------------------------18467633426500":["","","","","","","","","","",""],"Content-Disposition: form-data; name":["\"personsNameText\"","\"centreEmailAddressText\"","\"centreTelephoneNumberText\"","\"centreNumberText\"","\"centreNameText\"","\"invoiceText\"","\"currencyText\"","\"amountText\"","\"cardtypeText\"","\"commentsText\"","\"declarationText\""],"name9":"","name9@name.com":"","ab123":["",""],"GBP":"","Credit card":"","C":"","true":"","-----------------------------18467633426500--":""}}
      • 确保你知道你的数据类型,因为那里有一个称为“表单数据”的高阶键,它看起来像是把东西弄乱了。主要思想是:创建一个 FormData 对象和 append 您希望发送的键值对。
      • 是的。我不明白额外数据的来源,例如“表单数据”,因为来源是 obj2 的内容,它只是名称:值对。是的,我也一直在使用 .append() 。我会发布我有的任何突破。谢谢,弗拉德。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多