convert json object data to x-www-form-urlencoded

2020-07-10 06:21发布

问题:

I wish to convert json object into x-www-form-urlencoded How can I achieve this in angular 2 final release

export class Compentency {
  competencies : number[];
}
postData() {
        let array =  [1, 2, 3];
        this.comp.competencies = array;
        let  headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
        let options = new RequestOptions({ headers: headers, method: 'post' });
        return this.http.post(this.postUrl, JSON.stringify(this.comp), options)
        .map(res => res.json().data.competencies)
        .catch(this.handleError);
    }

回答1:

application/x-www-form-urlencoded

Control names and values are escaped. Space characters are replaced by +', and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., %0D%0A'). The control names/values are listed in the order they appear in the document. The name is separated from the value by=' and name/value pairs are separated from each other by `&'.

Therefore you will need to transform your JSON object. I would simply iterate over the JSON and output: encodeURIComponent(propertyKey) + "=" + encodeURIComponent(propertyValue) and will combine them using the & sign. e.g.

   var str = [];
    for (var key in obj) {
         if (obj.hasOwnProperty(key)) {
               str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]))                  
               console.log(key + " -> " + obj[key]);
         }
    }
    return str.join("&");


回答2:

use querystring,

npm install querystring

var querystring = require('querystring')

var inputJson = {
   name: "Asdf",
    age: 23
}

console.log(querystring.stringify(inputJson))

This will convert your json into application/x-www-form-urlencoded



回答3:

Assume have an object named postdata as below:

const postdata = {
  'a':1,
  'b':2,
  'c':3
};

and, you want convert it into x-www-form-urlencoded format, like: a=1&b=2&c=3

with URLSearchParams it's very easy to do it.

const rawData = new URLSearchParams(Object.keys(postdata).map(key=>[key,postdata[key]]));
console.log(rawData.toString());//a=1&b=2&c=3


回答4:

The non-recursive variant can be expressed as a one-liner with ES6 / TypeScript:

const formEncodedBody = Object.keys(obj).filter(k => obj.hasOwnProperty(k)).map(
        k => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k])).join('&');

Note that this algorithm (as the other solution as well) makes some assumptions:

  • The properties of the objects are all non-null (but that could be filtered)
  • The string representation of each property is exactly what shall be sent (e.g. no special treatment of arrays, booleans as true/false, not as 0/1 or yes/no...)
  • No recursion (no property is an object).


回答5:

private String toFormString(Object t)
{
    boolean needConectFlag = false;
    StringBuilder result = new StringBuilder();
    BeanInfo info;
    try
    {
        info = Introspector.getBeanInfo(t.getClass());
    }
    catch (IntrospectionException e)
    {
        throw new HttpMessageConversionException("failed  to getBeanInfo", e);
    }
    PropertyDescriptor[] descriptors = info.getPropertyDescriptors();

    for (PropertyDescriptor d : descriptors)
    {
        Method getMethod = d.getReadMethod();//Read对应get()方法
        Object retValue = null;
        try
        {
            retValue = getMethod.invoke(t);
        }
        catch (IllegalAccessException e)
        {
            throw new HttpMessageConversionException("failed  to invoke,IllegalAccess", e);
        }
        catch (IllegalArgumentException e)
        {
            throw new HttpMessageConversionException("failed  to invoke,IllegalArgument", e);
        }
        catch (InvocationTargetException e)
        {
            throw new HttpMessageConversionException("failed  to invoke,InvocationTarget", e);
        }
        if (retValue != null && !d.getName().equals("class"))
        {
            if (needConectFlag)
            {
                result.append("&");
            }
            result.append(d.getName()).append("=").append(retValue);

            needConectFlag = true;
        }
    }
    return result.toString();
}