使用“application/x-www-form-urlencoded”内容类型请求标头时,未正确发送 HttpClient 后正文参数

Posted

技术标签:

【中文标题】使用“application/x-www-form-urlencoded”内容类型请求标头时,未正确发送 HttpClient 后正文参数【英文标题】:HttpClient post body param is not sent correctly when using 'application/x-www-form-urlencoded' content type request header 【发布时间】:2018-08-02 06:42:29 【问题描述】:

我正在使用 httpClient 发布请求,例如:

我已经在 app.module.js 中为 http get 和 post 请求导入了 HttpClientModule。

const httpOptionsWithCookie = 标头:新的 HttpHeaders( 'Content-Type': 'application/x-www-form-urlencoded'), withCredentials: 真 ;

this.baseUrl(“API 链接”)

postArguments 是一个类似“ name:"xyz",company:"abc""的对象

this.http.post(this.baseUrl, postArguments, httpOptionsWithCookie);

我在前端使用 angular5,在后端使用 spring mvc 我是 angular5 的新手。

API 端代码:

**spring mvc 导入

             @RestController
             @RequestMapping(value = "/api/leavePeriod")
             public class LeavePeriodControllerApi 
     private static LogHelper logHelper = LogHelper
        .getInstance(LeaveApplicationControllerApi.class);

    @Autowired
    HttpSession session;

    @Autowired
    Environment env;

    @Autowired
    ILeavePeriodService service;

    @Autowired
    ISecurityCommonService securityCommonService;

    @Autowired
    ILeaveCategoryService leaveCategoryService;

    @Autowired
    ICompanyService companyService;

    @Autowired
    LeavePeriodValidator leavePeriodValidator;

  private User user = new User();
    private String LOGINUSER = "";

 @RequestMapping(value = "/viewLeavePeriod", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object>  viewLeavePeriod( @ModelAttribute LeavePeriodForm form,HttpServletRequest request,@RequestParam(value ="companyId" ,required = false)
    String companyId, @RequestParam(value ="leaveCategoryId", required = false)
    String leaveCategoryId )throws HRAlignBaseException 
     user = (User) session.getAttribute("user");
        LOGINUSER = "LoginUser " + user.getEmpName() + " loginuser empCode "
                + user.getEmpCode();    
        Map<String, Object> returnMap = new HashMap<String, Object>();

     try
         if(companyId!= null && companyId!="")
         
             form.setCompanyId(Integer.parseInt(companyId)); 
         
         if(leaveCategoryId!= null && leaveCategoryId!="")
         
             form.setLeaveCategoryId(Integer.parseInt(leaveCategoryId));
         

         returnMap = service.view(form);
         returnMap.put("periodList", form.getLeavePeriodVoList());
         returnMap.put("comId", form.getCompanyId());
         returnMap.put("leaveCatId", form.getLeaveCategoryId());
         catch (Exception e) 
            e.printStackTrace();
        
        logHelper
        .info("################"
                + LOGINUSER
                + "############# END Enter LeavePeriodController viewLeavePeriod");
        return returnMap;
    

相同的 http post 请求在 angularjs 中有效,但在 angular5 中无效。

此外,当从 ARC 执行相同的 http 帖子时,它工作正常,但不适用于 angular5

【问题讨论】:

【参考方案1】:

对于“Content-Type”:“application/x-www-form-urlencoded”表单数据应该像“menuId=5&buttonRights=adfasdfad&abc=aasdfasdfd”一样发送,而不是json格式,所以这个功能在angularjs(ngResource)中可用但不是角度 5(HttpClient)。 这是发布数据的标准方式。 下面的代码是针对简单对象的。

   import  URLSearchParams  from "@angular/http"


   testRequest() 
   let data = new URLSearchParams();
    data.append('username', username);
    data.append('password', password);

   this.http
    .post('/api', data)
    .subscribe(data => 
        alert('ok');
     , error => 
      console.log(error.json());
     );
     

如果要发布对象或嵌套对象,则必须使用以下代码手动将对象转换为查询字符串。

       jsonTransformRequest (data) 
          var param = function (obj) 
           var query = '';
        var name, value, fullSubName, subValue, innerObj, i;

     for (name in obj) 
      value = obj[name];

      if (value instanceof Array) 
          for (i = 0; i < value.length; ++i) 
              subValue = value[i];
              fullSubName = name + '[' + i + ']';
              innerObj = ;
              innerObj[fullSubName] = subValue;
              query += param(innerObj) + '&';
          
       else if (value instanceof Object) 
          for (let subName in value) 
              subValue = value[subName];
              fullSubName = name + '.' + subName;
              innerObj = ;
              innerObj[fullSubName] = subValue;
              query += param(innerObj) + '&';
          
       else if (value !== undefined && value !== null) 
          query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
      
  
  return query.length ? query.substr(0, query.length - 1) : query;
      ;
       var ret =  (data != null && typeof data === 'object') ? param(data) : 
     data;
      return ret;
     ;

【讨论】:

以上是关于使用“application/x-www-form-urlencoded”内容类型请求标头时,未正确发送 HttpClient 后正文参数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XMLHttpRequest 发送 POST 数据

测试2

Python-提交json请求

Python-提交json请求

Python-提交json请求

@RequestParam和@RequestBody的区别