如何为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)
答案 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)
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