php - Swift 中的 HTTP Post 到 PHP 给出 code=3840
问题描述
我正在尝试向我的服务器发送一个应用程序收据字符串,该服务器反过来查询 Apple 的 verifyReceipt 端点,但是我收到以下错误:
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}
如果我将收据字符串硬编码到我的 PHP 中,我会收到正确的 JSON 输出,如下所示:
string(2759) "{ "receipt":{"receipt_type":"ProductionSandbox", "adam_id":0, "app_item_id":0, "bundle_id":"com.Test.SQLExplorer", "application_version":"1", "download_id":0, "version_external_identifier":0, "receipt_creation_date":"2020-05-06 15:24:21 Etc/GMT", "receipt_creation_date_ms":"1588778661000", "receipt_creation_date_pst":"2020-05-06 08:24:21 America/Los_Angeles", "request_date":"2020-05-06 15:55:01 Etc/GMT", "request_date_ms":"1588780501918", "request_date_pst":"2020-05-06 08:55:01 America/Los_Angeles", "original_purchase_date":"2013-08-01 07:00:00 Etc/GMT", "original_purchase_date_ms":"1375340400000", "original_purchase_date_pst":"2013-08-01 00:00:00 America/Los_Angeles", "original_application_version":"1.0", "in_app":[ {"quantity":"1", "product_id":"com.Test.SQLExplorer.extrasubject", "transaction_id":"1000000659868895", "original_transaction_id":"1000000659868895", "purchase_date":"2020-05-04 10:55:57 Etc/GMT", "purchase_date_ms":"1588589757000", "purchase_date_pst":"2020-05-04 03:55:57 America/Los_Angeles", "original_purchase_date":"2020-05-04 10:55:57 Etc/GMT", "original_purchase_date_ms":"1588589757000", "original_purchase_date_pst":"2020-05-04 03:55:57 America/Los_Angeles", "is_trial_period":"false"}, {"quantity":"1", "product_id":"com.Test.SQLExplorer.IAP2", "transaction_id":"1000000659963594", "original_transaction_id":"1000000659963594", "purchase_date":"2020-05-04 14:27:40 Etc/GMT", "purchase_date_ms":"1588602460000", "purchase_date_pst":"2020-05-04 07:27:40 America/Los_Angeles", "original_purchase_date":"2020-05-04 14:27:40 Etc/GMT", "original_purchase_date_ms":"1588602460000", "original_purchase_date_pst":"2020-05-04 07:27:40 America/Los_Angeles", "is_trial_period":"false"}, {"quantity":"1", "product_id":"com.Test.SQLExplorer.IAP3", "transaction_id":"1000000660362367", "original_transaction_id":"1000000660362367", "purchase_date":"2020-05-05 12:55:01 Etc/GMT", "purchase_date_ms":"1588683301000", "purchase_date_pst":"2020-05-05 05:55:01 America/Los_Angeles", "original_purchase_date":"2020-05-05 12:55:01 Etc/GMT", "original_purchase_date_ms":"1588683301000", "original_purchase_date_pst":"2020-05-05 05:55:01 America/Los_Angeles", "is_trial_period":"false"}, {"quantity":"1", "product_id":"com.Test.SQLExplorer.IAP1", "transaction_id":"1000000659963406", "original_transaction_id":"1000000659963406", "purchase_date":"2020-05-04 14:26:57 Etc/GMT", "purchase_date_ms":"1588602417000", "purchase_date_pst":"2020-05-04 07:26:57 America/Los_Angeles", "original_purchase_date":"2020-05-04 14:26:57 Etc/GMT", "original_purchase_date_ms":"1588602417000", "original_purchase_date_pst":"2020-05-04 07:26:57 America/Los_Angeles", "is_trial_period":"false"}]}, "status":0, "environment":"Sandbox"}"
但是,当我在以下 HTTP POST 请求中使用它时,它会因错误而失败,这表明问题出在其中。有什么想法我哪里出错了吗?
邮政
func sendReceipt(receiptString: String) {
let basePath = "https://www.example.com/validate.php"
let pathAsURL: URL = URL(string: basePath)!
let parameterDictionary = ["encodedReceipt" : receiptString]
var request = URLRequest(url: pathAsURL)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameterDictionary, options: []) else { return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
}catch {
print(error)
}
}
}
.resume()
}
PHP
<?php
//Read input from POST request
$inputreceipt = json_decode(file_get_contents('php://input'), true);
//Get receiptstring from json input
$receipt_data = $inputreceipt['encodedReceipt'];
//JSON bundle to be sent to app store
$data = json_encode(["receipt-data" => $receipt_data]);
//$url = "https://buy.itunes.apple.com/verifyReceipt"; //production
$url = "https://sandbox.itunes.apple.com/verifyReceipt"; //sandbox
echo post($url,$data);
function post($url, $data, $headerArray = array())
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if (array() === $headerArray)
curl_setopt($curl, CURLOPT_HTTPHEADER,["Content-type:application/json;charset='utf-8'","Accept:application/json"]);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
?>
解决方案
我最终解决了几个问题:
1)在sendReceipt
方法
let parameterDictionary = ["encodedReceipt" : "\(receiptString)"]
更改为let parameterDictionary = ["encodedReceipt" : receiptString]
2) 在 PHP
var_dump(post($url,$data));
中为返回的 JSON 添加了很多额外的东西。改为压制echo post($url,$data);
。
如果有人感兴趣,原始帖子已更新为正确的工作代码。
推荐阅读
- java - HTTP 状态 404 - 未找到:对于控制器 - 在 Idea 中找不到视图解析器
- angular - 无论我做什么,都找不到 FormGroup 和 FormControl
- python - 为什么我的范围函数不是从“开始”值开始?
- firebase - MissingPluginException(在通道 plugins.flutter.io/firebase_auth 上找不到方法 signInAnonymously 的实现)
- extjs - 点击监听器不工作没有错误
- python - Python - Pandas 组合了两个提供不同值的数据框
- javascript - 更换从条码打印机打印的小程序
- python - 使用 backtesting.py 回测交易策略
- javascript - 多次反应组件渲染
- kubernetes - Kubernetes master 离线场景