给Parse.Cloud.httpRequest添加JSON支持 "application/x-www-form-urlencoded"

3
我一直在尝试将Stripe的托管帐户实现到我的云代码函数中。目前为止,我已经成功了,但是现在我遇到了一个似乎无法解决的问题。
具体来说: 使用“content_type:'application/x-www-form-urlencoded'”,我如何发送JSON?
由于Stripe期望表单urlencode,因此无法将content_type更改为“application/JSON”。我尝试对JSON进行字符串化,但是当我这样做时,Stripe也会抱怨。它期望一个“散列”,我认为这是一个JSON。
是否可以对JSON进行URL编码,以便在仍将content_type设置为form-urlencoded的情况下发送它?
我的当前代码无法工作,因为Parse说:
引发错误:无法形成编码对象。
var secret_key = stripeKeys.stripeSecretKey;
var cardTokenId = "tok_...";
var country = "BE";
var currency = "EUR";
var email = "test@test.org";
var firstName = "test";
var lastName = "tester";
var dobDay = 1;
var dobMonth = 1;
var dobYear = 1950;
var addressCity = "City";
var addressCountry = "Country";
var addressLine = "Address line";
var addressZIP = "ZIP";
var addressProvince = "Province";       

var createAccountPromise = function()
{
    var params = 
        {
            url: "https://api.stripe.com/v1/accounts",
            method: "POST",
            headers: 
            {
                "Authorization": "Basic " + new Buffer(secret_key + ":").toString("base64"),
                "content_type": "application/x-www-form-urlencoded"
            },
            body: 
            {   
                "country": country,
                "default_currency": currency,
                "email": email,
                "managed": true,
                "legal_entity":
                    {
                        "first_name": firstName,
                        "last_name": lastName,
                        "type": "individual",
                        "dob":
                            {
                                "day": dobDay,
                                "month": dobMonth,
                                "year": dobYear
                            },
                        "personal_address":
                            {
                                "city": addressCity,
                                "country": addressCountry,
                                "line1": addressLine,
                                "postal_code": addressZIP,
                                "state": addressProvince
                            }
                    },
                "external_account": cardTokenId
            }
        };
    return Parse.Cloud.httpRequest(params);
}

createAccountPromise()
    .then(function(result)
    {
        console.log("SUCCESS: " + result.text);
        response.success("Account Created");
    },
    function(errorReason)
    {
        console.log("ERROR: " + errorReason.text);
        response.error("Account NOT Created because: " + errorReason.text);
    });
2个回答

3
问题在于,application/x-www-form-urlencoded的Content-Type会导致“平坦”的key=value属性列表,而您正在传递一个具有多个级别的分层对象。JSON知道如何编码这样的对象,但application/x-www-form-urlencoded则不知道(有几种不同的方法可以解决此问题,例如点符号表示法、括号等等)。
您应该将JSON对象“展平”,使其仅有一个级别,并使用“扩展”名称作为键。即,不要再使用包含first_namelegal_entity,而是直接设置legal_entity[first_name](以匹配Stripe使用的格式)。
所以,您的请求体应该是:
body: 
{   
    "country": country,
    "default_currency": currency,
    "email": email,
    "managed": true,
    "legal_entity[first_name]": firstName,
    "legal_entity[last_name]": lastName,
    "legal_entity[type]": "individual",
    "legal_entity[dob][day]": dobDay,
    "legal_entity[dob][month]": dobMonth,
    "legal_entity[dob][year]": dobYear
    "legal_entity[personal_address][city]": addressCity,
    "legal_entity[personal_address][country]": addressCountry,
    "legal_entity[personal_address][line1]": addressLine,
    "legal_entity[personal_address][postal_code]": addressZIP,
    "legal_entity[personal_address][state]": addressProvince
    "external_account": cardTokenId
}

当然,如果你有更复杂的对象,可以在代码中“展平”它们,而不是手动处理。

另外,应该使用Content-Type,而不是content_type


谢谢解释!它有效 :) 尽管 content_type 或 Content-type 并不重要,我尝试了两种方式,它们都可以工作。 - TheTool

0

使用encodeURIComponent将JSON转换为x-www-form-urlencoded格式,然后发送请求。

return Parse.Cloud.httpRequest(encodeURIComponent(params));

或者

return Parse.Cloud.httpRequest(encodeURIComponent(JSON.stringify(params)));

这给了我一个错误:无法调用未定义的 'toUpperCase' 方法。 - TheTool
可能是因为 params 对象的一个或多个属性未定义。在调用函数时,请检查 params 对象的所有值。 - Gor
我更新了代码,告诉我你需要什么,我会提供给你的 :) - TheTool
请在返回 Parse.Cloud.httpRequest(params) 之前,将此行代码添加到您的代码中:console.log(JSON.stringify(params, null, 4)),然后运行代码并发送输出。 - Gor
让我们在聊天室中继续这个讨论 - Gor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接