url将php数据编码为json对象 [英] url encoding php data into json object
问题描述
请阅读-这不仅仅是将json_encode从php转换为javascript.
Please read - this isn't just simply doing json_encode from php to javascript.
我们的计费系统使用Authorize.net.使用PHP中的Authorize.net API,我们创建令牌请求.请求中的数据传递客户信息,余额,账单地址等-该数据直接通过PHP发送.作为响应,我们得到了一个用PHP处理的令牌-然后将该令牌嵌入到HTML表单输入中.
Our billing system uses Authorize.net. Using the Authorize.net API, in PHP we create a token request. The data in the request passes customer info, balance, billing address, etc - that data is sent directly with PHP. In response we get a token to be processed in PHP - and then that token is embedded into the HTML form input.
提交信用卡表单后,我们会收到一个javascript json响应,该表单将返回其他JS函数处理的表单.一切正常,直到我们有一个客户的公司名称为&
(即: Bar& Grill
)
After the credit card form is submitted, we get a javascript json response back to the form to be processed by other JS functions. All works fine until we have a customer with the &
in their company name (IE: Bar & Grill
)
&
仅在返回到表单的json响应中触发错误-具体来说,我们得到的错误是: json输入的意外结尾
,这会导致其余错误的脚本.
The &
triggers an error only in the json response back to the form - specifically the error we get is: unexpected end of json input
which causes the rest of the scripts to error out.
因此,问题是,是否需要对PHP令牌请求中的客户数据进行urlencoded-还是有一种特殊的方式来处理json响应?据我所知,Authorize只是在json响应中返回确切的客户数据-因此,如果我们在前端对url进行编码(在发送令牌请求之前),那么这是否意味着我们还需要对json响应进行url解码
So, the issue is, does the customer data in the PHP token request need to be urlencoded - or is there a special way to handle the json response? From what I can tell, Authorize simply returns the exact customer data in the json response - so if we url encode it on the front end (before the token request is sent), then does that mean we also need to url decode the json response.
首先出现的问题是鸡肉和鸡蛋.
Its kind of a chicken and an egg which came first problem.
Authorize.net令牌请求(在PHP中):
Authorize.net Token Request (in PHP):
$customerData = new AnetAPI\CustomerDataType();
$customerData->setType("business");
$customerData->setId($ss['authCustID']);
$customerData->setEmail($ii['cEmail']);
// Set the Bill To info for new payment type
$billTo = new AnetAPI\CustomerAddressType();
$billTo->setFirstName($ii['cFirstName']);
$billTo->setLastName($ii['cLastName']);
$billTo->setCompany($ii['cName']); // #1 <----- IE: "Bar & Grill"
$billTo->setAddress($ii['cAddress']. " " .$ii['cAddress1']);
$billTo->setCity($ii['cCity']);
$billTo->setState($ii['cState']);
$billTo->setZip($ii['cZip']);
$billTo->setCountry("USA");
// set shipping profile
$shipTo = clone $billTo ;
// extend billTop profile
$billTo->setFaxNumber('8005551212') ;
$billTo->setPhoneNumber($ii['cPhone']);
//create a transaction
$transactionRequestType = new AnetAPI\TransactionRequestType();
$transactionRequestType->setTransactionType("authCaptureTransaction");
$transactionRequestType->setAmount($ss['balance']);
$transactionRequestType->setCustomer($customerData) ;
$transactionRequestType->setOrder($order) ;
$transactionRequestType->setBillTo($billTo) ;
$transactionRequestType->setShipTo($shipTo) ;
// Build transaction request
$request = new AnetAPI\GetHostedPaymentPageRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setTransactionRequest($transactionRequestType);
//execute request
$controller = new AnetController\GetHostedPaymentPageController($request);
$response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::PRODUCTION); // SANDBOX or PRODUCTION
$gToken=[] ;
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) {
//echo $response->getToken()."\n";
$gToken["Error"] = 0 ;
$gToken["Token"] = $response->getToken() ;
} else {
//echo "ERROR : Failed to get hosted payment page token\n";
$errorMessages = $response->getMessages()->getMessage();
//echo "RESPONSE : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n";
$gToken["Error"] = 1 ;
$gToken["errMsg"] = $errorMessages[0]->getCode() . ": " .$errorMessages[0]->getText() ;
}
Form/JSON响应处理程序:
Form/JSON response handler:
AuthorizeNetPopup.onReceiveCommunication = function (querystr) {
var params = parseQueryString(querystr);
//console.log(params) ;
switch (params["action"]) {
case "successfulSave":
AuthorizeNetPopup.closePopup();
break;
case "cancel":
AuthorizeNetPopup.closePopup();
break;
case "transactResponse":
// 'response' is a string value
// encode it as an object, to be passed to global function
// that will decode it again for PHP
console.log(params["response"]) ;
var response = JSON.parse(params["response"]); // #2 <--- ERROR: unexpected end of json input
//var response = params["response"];
httpReceipt(response) ;
AuthorizeNetPopup.closePopup();
break;
case "resizeWindow":
var w = parseInt(params["width"]);
var h = parseInt(params["height"]);
var ifrm = document.getElementById("iframeAuthorizeNet");
ifrm.style.width = w.toString() + "px";
ifrm.style.height = h.toString() + "px";
centerPopup();
break;
}
};
我是在#1处对数据进行url编码(在php部分中)还是在处理json响应之前(在#2处)对json响应进行url编码?如何处理这个问题非常困惑.我们是否需要对添加到令牌请求中的每个参数的数据进行编码-还是可以在提交整个请求之前对其进行编码?不管在通信的哪一端应用编码/解码,正确的编码/解码调用是什么?
Do I url encode data at #1 (in php section) or do I url encode the json response before processing it (at #2) - or both? Very confused on how to handle this. Do we need to encode the data of eachparameter being added to the token request - or can we just encode the entire request before its submitted? Regardless of which end of the communication gets encoding/decoding applied, what are the proper encoding/decoding calls?
为说明流程:
- paymentPage.html-> PHP生成令牌,将令牌嵌入页面形式,还具有用于
paymentPageFrame.html
的iframe - paymentPageFrame.html->iFrame通讯器页面,可在paymentPage.html和authorize.net之间中继消息
- paymentPage.html->javascript
onReceiveCommunication
处理来自paymentPageFrame.html 的消息
- paymentPage.html ->PHP generates token, embeds token into page form, also has iframe for
paymentPageFrame.html
- paymentPageFrame.html -> iFrame communicator page, relays msgs between paymentPage.html and authorize.net
- paymentPage.html -> javascript
onReceiveCommunication
to process messages coming from paymentPageFrame.html
事实证明,authorize.net正在将URL字符串返回给paymentPageFrame.html-该字符串未使用urlencoded.然后将字符串传递回父 onReceiveCommunication
,在该位置使用自定义解析器对其进行解析:
Turns out that authorize.net is returning a URL string to paymentPageFrame.html - the string is not urlencoded. The string is then getting passed back to the parent onReceiveCommunication
at which point its being parsed with a custom parser:
function parseQueryString(str) {
var vars = [];
var arr = str.split('&');
var pair;
for (var i = 0; i < arr.length; i++) {
pair = arr[i].split('=');
vars.push(pair[0]);
vars[pair[0]] = unescape(pair[1]);
}
return vars;
}
然后,此自定义解析器使其中包含&
的数据值(即:"company":"Bar& Grill")将名称一分为二,最终导致到json输入的无效/意外末端.
This custom parser is then causing a data value that has the &
in it (IE: "company" : "Bar & Grill") to split the name in half ultimately leading to the invalid/unexpected end of json input.
string
被传递回iFrame,而iFrame又传递给iFrame:
The string
being passsed back to the iFrame, which in turn gets passed to the parent is:
action=transactResponse&response={"accountType":"Visa","accountNumber":"XXXX0623","transId":"62830720474","responseCode":"1","authorization":"185778","shipTo":{"firstName":"Bob","lastName":"Jones","company":"Backyard Bar & Grill","address":"123 Main St ","city":"Tampa","state":"FL","zip":"33606","country":"USA"},"orderDescription":"2020-12-01 bill for All Regions/All Sites","customerId":"1002-0","totalAmount":"1.50","orderInvoiceNumber":"11386-0","dateTime":"2/2/2021 4:57:53 PM","refId":"ref1612285039"}
现在该字符串在父页面中,我试图找出对其进行编码然后对其进行解析的最佳方法,以便在数据值中包含&
时在解析时不会中断它(即:后院酒吧和烧烤店
)
Now that the string is in the parent page, I am trying to figure the best way to encode it then parse it so it won't break on parsing when a data value has &
in it (IE: Backyard Bar & Grill
)
到目前为止,我一直在尝试,没有成功:
So far I am trying, without sucess:
var urlstr = encodeURIComponent(response) ; // encode it first
var newUrl = new URLSearchParams(urlstr) ; // then proper parse it
但是当我尝试访问参数时,它返回null:
But when I try to access the parameters, it returns null:
consoole.log(newUrl.get('action')) ;
> null
推荐答案
经过反复修改,我终于写了自己的解析器,该解析器是:
After much tinkering around, i finally wrote my own parser that:
A:如果存在,请先捕获响应JSON
A: if exists, capture the response JSON first
B:然后解析URL参数的其余部分:
B: then parse the remainder of the URL params:
C:将所有参数和响应对象作为单个对象返回
C: return all params and response object as a single object
var str = 'action=transactResponse&response={"accountType":"Visa","accountNumber":"XXXX0623","transId":"62830720474","responseCode":"1","authorization":"185778","shipTo":{"firstName":"Preston","lastName":"Rolinger","company":"Backyard & Grill","address":"2808 W Foster Ave S ","city":"Tampa","state":"FL","zip":"33611","country":"USA"},"orderDescription":"2020-12-01 bill for All Regions/All Sites","customerId":"1002-0","totalAmount":"1.50","orderInvoiceNumber":"11386-0","dateTime":"2/2/2021 4:57:53 PM","refId":"ref1612285039"}&moreKey="other value"' ;
function parseResponse(str) {
var resInfo = [], res = {} ;
if (str.match("&response=")) {
var params = str.split("&response=") ; // leading params & response obj
if (params[1].match("}&")) {
resInfo = params[1].split("}&") ; // splits off anything at end of obj
res.response = JSON.parse(resInfo[0] + "}") ; // add } to complete obj string again
} else {
res.response = JSON.parse(params[1]) ; // else it already is the json string
}
if (resInfo[1]) {
params = params[0]+ "&" +resInfo[1] ; // join url params back together
} else {
params = params[0] ;
}
} else {
params = str ; // else the str has no "response" in it, process just params
}
params = new URLSearchParams(encodeURI(params)) ; //encode then parse
params.forEach(function(value, key) {
res[key] = value ;
}) ;
return res ;
}
var response = parseResponse(str) ;
console.log(response) ;
这篇关于url将php数据编码为json对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!