angular2中的httpParamSerializerJQLike?

时间:2016-04-13 16:52:14

标签: http post typescript angular ionic2

如何为Ruby API序列化JSON?

Angular 1

$scope.submitForm = function() {       
    var data = {"contato": $scope.contato, "id":$scope.contato.id, "_method":'PUT'};
    $http.post(
        'http://myApi/contatos/' + $scope.contato.id,
        **$httpParamSerializerJQLike(data)**,
        {
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            datatype: "JSONP"
        }).then(function successCallback(response) {
            modalContato.show();
            setTimeout(function (){
                modalContato.hide();
                $state.go('contato-detalhe', {"id":$scope.contato.id});
            }, 1500);              

    });
};    

Angular2:

insertContato(contato: Contato) {
  let headers = new Headers({
    'Content-Type': 'application/x-www-form-urlencoded'        
  });      
  let options = new RequestOptions({ headers: headers });
  this._http    
    .post(this.urlApi + '/contatos', JSON.stringify(contato), options)      
    .subscribe(data => {
      console.log('Funciona: ' + data.text());
    }, error => {
      console.log('Erro: ' + error.text())
    });           
}

" JSON.stringify(contato)" 它与$ httpParamSerializerJQLike(数据)的行为不同。 Json在服务器上坏了......

  

开始发布" / contatos"对于127.0.0.1在2016-04-13 13:25:55 -0300   由ContatosController处理#create as HTML     参数:{" {\" nome \":\" asd \",\" email \":\" asd @ asda.com \" \" telefone \":\" 123 \"}" = GT;零}   在4ms内完成400 Bad Request(ActiveRecord:0.0ms)

正确的是:

  

开始发布" / contatos"在2016-04-12 17:00:24 -0300的127.0.0.1   由ContatosController处理#create as JSON     参数:{" contato" => {" nome" =>" felipe"," telefone" =>" 5555"}}   在278ms完成200 OK(浏览次数:0.1ms | ActiveRecord:229.4ms)

5 个答案:

答案 0 :(得分:3)

我有类似的问题,我可以解决这个问题:

import { Headers, Http, Response, URLSearchParams, RequestOptions } from '@angular/http';

let headers = new Headers({
     'Content-Type': 'application/x-www-form-urlencoded',
     'Accept': '*/*'});
  let options = new RequestOptions({ headers: headers });
  let body = new URLSearchParams();

  body.set("message", JSON.stringify(m_dataRequest));
  body.set("webService", "authService");

  return this.http
             .post(this.Url, body.toString(), options)
             .toPromise()
             .then(this.extractData)
             .catch(this.handleError);

URLSearchParams规范化了表格和管道dimiss的参数,这对我来说很有用。 我希望这能解决你的问题。

答案 1 :(得分:0)

我要说这可能不是解决这个问题的最佳方法,但这是我如何为自己解决这个问题(Angular 2 docs don'似乎在任何地方都提到了x-www-form-urlencoded。

因此,如果您的数据设置为

var data = {"contato": $scope.contato, "id":$scope.contato.id, "_method":'PUT'};

您希望自己基本上将其转换为表单。

var encodedData = "contato=" + contato + "&id=" + contato.id + "&_method=PUT";

然后你可以修改你的POST请求看起来像这样

this._http    
.post(this.urlApi + '/contatos', encodedData, options)      
.subscribe(data => {
  console.log('Funciona: ' + data.text());
}, error => {
  console.log('Erro: ' + error.text())
});

没有JSON.stringify它,因为你没有传递json,你传递表单数据。

我希望这会有所帮助。

答案 2 :(得分:0)

我在http.ts提供程序中编写了一个函数,如此---

private formatData(data){
    let returnData = '';
    console.log(data);
    let count = 0;
    for (let i in data){
        if(count == 0){
            returnData += i+'='+data[i];
        }else{
            returnData += '&'+i+'='+data[i];
        }
        count = count + 1;
        console.log(returnData);
    }
    return returnData;
}

这样称呼它。

post('localhost/url',data){
data = this.formatData(data);
}

答案 3 :(得分:0)

只需复制angularjs http module

中的相关代码即可
import {
  isArray,
  forEach,
  isObject,
  isDate,
  isFunction,
  isUndefined,
  isNumber,
} from 'lodash';

function toJsonReplacer(key, value) {
  let val = value;

  if (
    typeof key === 'string' &&
    key.charAt(0) === '$' &&
    key.charAt(1) === '$'
  ) {
    val = undefined;
  }

  return val;
}

function toJson(obj, pretty = undefined) {
  if (isUndefined(obj)) return undefined;
  if (!isNumber(pretty)) {
    pretty = pretty ? 2 : null; // tslint:disable-line no-parameter-reassignment
  }
  return JSON.stringify(obj, toJsonReplacer, pretty);
}

function serializeValue(v) {
  if (isObject(v)) {
    return isDate(v) ? v.toISOString() : toJson(v);
  }
  return v;
}

function forEachSorted(obj, iterator, context = null) {
  const keys = Object.keys(obj).sort();
  for (let i = 0; i < keys.length; i += 1) {
    iterator.call(context, obj[keys[i]], keys[i]);
  }
  return keys;
}

/**
 * This method is intended for encoding *key* or *value* parts of query component. We need a custom
 * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
 * encoded per http://tools.ietf.org/html/rfc3986:
 *    query         = *( pchar / "/" / "?" )
 *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
 *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 *    pct-encoded   = "%" HEXDIG HEXDIG
 *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
 *                     / "*" / "+" / "," / ";" / "="
 */
function encodeUriQuery(val, pctEncodeSpaces = undefined) {
  return encodeURIComponent(val)
    .replace(/%40/gi, '@')
    .replace(/%3A/gi, ':')
    .replace(/%24/g, '$')
    .replace(/%2C/gi, ',')
    .replace(/%3B/gi, ';')
    .replace(/%20/g, pctEncodeSpaces ? '%20' : '+');
}

export function jQueryLikeParamSerializer(params) {
  if (!params) return '';
  const parts = [];
  serialize(params, '', true);
  return parts.join('&');

  function serialize(toSerialize, prefix, topLevel = undefined) {
    if (isArray(toSerialize)) {
      forEach(toSerialize, (value, index) => {
        serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
      });
    } else if (isObject(toSerialize) && !isDate(toSerialize)) {
      forEachSorted(toSerialize, (value, key) => {
        serialize(
          value,
          prefix + (topLevel ? '' : '[') + key + (topLevel ? '' : ']'),
        );
      });
    } else {
      if (isFunction(toSerialize)) {
        toSerialize = toSerialize(); // tslint:disable-line no-parameter-reassignment
      }
      parts.push(
        encodeUriQuery(prefix) +
          '=' +
          (toSerialize == null
            ? ''
            : encodeUriQuery(serializeValue(toSerialize))),
      );
    }
  }
}

答案 4 :(得分:0)

当从angular 1.x升级时,我遇到了类似的问题 这是我的解决方案,它也处理嵌套的JSON对象:

function Json2FormEncoded(json_obj) {
  let path = arguments[1] || '';
  let s = '', p = '';
  for (let i in json_obj) {
    p = path == '' ? i : path + '[' + i + ']';
    s = s ? s + "&" : s;
    if (typeof json_obj[i] == 'object') {
      s += Json2FormEncoded(json_obj[i], p);
    } else {
      s += p + '=' + encodeURIComponent(json_obj[i]);
    }
  }
  return s;
}

希望您会发现它有用!

也检查here