“ JSON文本不是以数组或对象开头,并且没有允许设置片段的选项。”

时间:2019-04-24 12:10:37

标签: php json swift post error-handling

在发出 POST 请求时,Xcode调试器显示错误

  

Error Domain = NSCocoaErrorDomain代码= 3840“ JSON文本不是以数组或对象开头,并且未设置允许片段的选项。 UserInfo = {NSDebugDescription = JSON文本不是以数组或对象开头,并且未设置允许片段的选项。}

这是POST功能,

 func startArchive() {

        let app_Id = (appId.base64Decoded()!)
        let job_Id = (jobId.base64Decoded()!)

        var response_ = 0

        guard let url = URL(string: "https://xxx.yyyy.com/question/abc") else {return}
        let request = NSMutableURLRequest(url:url)
        request.httpMethod = "POST"
        let postString = "session_id=\(pSessionId)&job_id=\(job_Id)&app_id=\(app_Id)&action=start"
        print(postString)
        request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.httpBody = postString.data(using: String.Encoding.utf8)

        let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
            guard error == nil && data != nil else {                                                          // check for fundamental networking error
                print("error=\(String(describing: error))")
                return
            }

            do {
                if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
                    print(responseJSON)
                    print(responseJSON["status"]!)                   
                    response_ = responseJSON["status"]! as! Int                    
                    print(response_)

                    //Check response from the sever
                    if response_ == 200
                    {
                        OperationQueue.main.addOperation {
                            print("Login Successful")
                        }                        
                    }                        
                    else
                    {
                        OperationQueue.main.addOperation {

                            print("Login Failed")

                        }                      
                    }
                }
            }
            catch {
                print("Error -> \(error)")
            }
        }
        task.resume()
    }

我尝试使用标头,但仍然出现相同的错误。

  

request.setValue(“ text / html; charset = UTF-8”,对于HTTPHeaderField:“ Content-Type”)

这是上述请求的PHP函数,

public function abc(Request $request)
{        $session_id = !empty($request->input('session_id')) ? $request->input('session_id') : '';
    $action = $request->input('action');
    $archiveId = !empty($request->input('archive_id')) ? $request->input('archive_id') : '';

    $data = array();

    $opentok = new \OpenTok\OpenTok($_SERVER['TOKBOX_' . strtoupper($this->tenantName) . '_API_KEY'], $_SERVER['TOKBOX_' . strtoupper($this->tenantName) . '_SECRET']);

    if ($action == 'start') { // Start recording
        try {
            // Create an archive using custom options
            $archiveOptions = array(
                'name' => 'Important Presentation', // default: null
                'hasAudio' => true, // default: true
                'hasVideo' => true, // default: true
                'outputMode' => \OpenTok\OutputMode::COMPOSED  // default: OutputMode::COMPOSED
            );

            $archive = $opentok->startArchive($session_id, $archiveOptions);

            $job_id = $request->input('job_id');
            $app_id = $request->input('app_id');

            // check record exist or not
            $check_archive = DB::table('practice_question_recordings')
                ->where('job_id', $job_id)
                ->where('app_id', $app_id)
                ->get();

            if (empty($check_archive)) { // insert data
                $insert_data = array();
                $insert_data['job_id'] = $job_id;
                $insert_data['app_id'] = $app_id;
                $insert_data['archive_id'] = $archive->id;
                $insert_data['archive_url'] = '';

                DB::table('practice_question_recordings')->insert($insert_data);
            } else {  // Update data
                $update_data = array();
                $update_data['job_id'] = $job_id;
                $update_data['app_id'] = $app_id;
                $update_data['archive_id'] = $archive->id;
                $update_data['archive_url'] = '';

                DB::table('practice_question_recordings')
                    ->where('job_id', $job_id)
                    ->where('app_id', $app_id)
                    ->update($update_data);
            }

            $data['status'] = 200;
            $data['archive_id'] = $archive->id;
            $data['message'] = 'Recording started successfully.';
        } catch (Exception $ex) {

            $data['status'] = 500;
            $data['message'] = $ex->getMessage();
        }
    } else { // Stop recording
        try {
            $archive_detail = $opentok->stopArchive($archiveId);

            $data['status'] = 200;
            $data['archive_detail'] = $archive_detail;
            $data['message'] = 'Recording stopped successfully.';
        } catch (Exception $ex) {
            $data['status'] = 500;
            $data['message'] = $ex->getMessage();
        }
    }

    return response()->json($data);
}

1 个答案:

答案 0 :(得分:0)

所以最终我能够检测到该问题。问题出在网址的子域部分。

  

https://first.yyyy.com/question/abc

由于我使用了另一个子域的会话ID [OpenTok],并将其作为参数传递给它,因此出现了状态码500。

  

https://second.yyyy.com/question/abc

此外,我将POST函数结构更改为:

    func startArchive() {

    let app_Id = (appId.base64Decoded()!)
    let job_Id = (jobId.base64Decoded()!)

    let parameters: [String: Any] = ["session_id": pSessionId, "job_id":job_Id, "app_id":app_Id, "action":"start"]

    print("Parameter:\(parameters)")
    guard let url = URL(string: "https://first.yyyy.com/question/abc") else {return}

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("iOS", forHTTPHeaderField: "deviceType")
    guard let httpbody = try? JSONSerialization.data(withJSONObject: parameters, 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{

            let mdata = String(data: data, encoding: .utf8)
            print("This is data: \(mdata!)")

            do{
                //                    print("\(String(data: data, encoding: .utf8) ?? "")")
                if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary {
                    DispatchQueue.main.async {
                        _archiveId = (json["archive_id"] as! String)
                        print(json)
                    }
                }
            } catch {
                print(error)
            }
        }
        }.resume()
}

对我来说效果很好,并以 JSON 返回了数据。