错误域 = NSCocoaErrorDomain 代码 = 3840 “JSON 文本不是以数组或对象开头

Posted

技术标签:

【中文标题】错误域 = NSCocoaErrorDomain 代码 = 3840 “JSON 文本不是以数组或对象开头【英文标题】:Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object 【发布时间】:2015-10-11 15:38:59 【问题描述】:

此代码的目的是使用 php 脚本将数据发送到 SQL 数据库。 但是当我尝试运行它时,我收到以下错误:

错误域=NSCocoaErrorDomain 代码=3840“JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。” UserInfo=NSDebugDescription=JSON 文本不以数组或对象开头,并且允许未设置片段的选项。

这是我的代码:

// Send userdata to server side
let myURL = NSURL(string: "http://localhost/userRegister.php");
let request = NSMutableURLRequest(URL:myURL!);
request.HTTPMethod = "POST";
let postString = "email=\(userEmail)&password=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);

// Create the task and execute it

let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data,response, error in

    if error != nil
    print("error=\(error)")
        return
    

    var err: NSError?

    do
    
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

        if let parseJSON = json 

            var resultValue = parseJSON["status"] as? String
            print("result: \(resultValue)")

            var isUserRegisterd:Bool = false;
            if(resultValue=="Success")
            
                isUserRegisterd = true
            

            var messageToDisplay: String = (parseJSON["message"] as? String)!

            if(!isUserRegisterd)
            
                messageToDisplay = (parseJSON["message"] as? String)!
            

            dispatch_async(dispatch_get_main_queue(), 

                var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert);
                let okAction = UIAlertAction(title: "Oké", style: UIAlertActionStyle.Default)
                    action in
                    self.dismissViewControllerAnimated(true, completion: nil);
                
                myAlert.addAction(okAction);
                self.presentViewController(myAlert, animated: true, completion: nil);
            );
        
    

    catch
    
        print(error)
    


task.resume()

这里有什么问题?

【问题讨论】:

顺便说一句,var err: NSError? 行是不需要的。此外,messageToDisplay 逻辑可能不太正确(例如,如果parseJSON 不包含键为message 的值,它将崩溃)。但是,在您担心这些事情之前,请先查看下面的 dataresponse,并弄清楚为什么您没有收到预期的 JSON 响应。 【参考方案1】:

该错误通常意味着 NSData 不包含有效的 JSON。

您应该查看responsedata 的字符串表示,因为如果服务器遇到问题,它很可能会在NSHTTPURLResponse 中返回statusCode(其中200 表示一切正常,RFC 2616 描述了其他错误代码的含义),NSData 可能包含 html 或描述问题性质的文本:

do 
    // your code where you `try` parsing the JSON response goes here
 catch 
    print(error)

    if data != nil 
        let string = String(data: data!, encoding: NSUTF8StringEncoding)
        print(string)
    

    print(response)

当您查看NSURLResponseNSData 对象时,您将更有可能诊断出问题。

--

顺便说一句,我可能会建议指定请求的Content-Type。另外,我建议对电子邮件地址和密码进行百分比转义。后者很重要,因为如果值包含特殊字符(例如 +& 是值得注意的问题),服务器将无法正确处理数据。

let url = NSURL(string: "http://localhost/userRegister.php")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let encodedEmail = userEmail.stringByAddingPercentEncodingForFormUrlencoded()
let encodedPassword = userPassword.stringByAddingPercentEncodingForFormUrlencoded()
let postString = "email=\(encodedEmail)&password=\(encodedPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

在哪里

extension String 

    /// Percent escape value to be added to a HTTP request
    ///
    /// This percent-escapes all characters besize the alphanumeric character set and "-", ".", "_", and "*".
    /// This will also replace spaces with the "+" character as outlined in the application/x-www-form-urlencoded spec:
    ///
    /// http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
    ///
    /// - returns: Return percent escaped string.

    func stringByAddingPercentEncodingForFormUrlencoded() -> String? 
        let allowedCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._* ")

        return stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacters)?.stringByReplacingOccurrencesOfString(" ", withString: "+")
    

或者,您可以通过以URLQueryAllowedCharacterSet 开头来构建允许字符的字符集,但您仍然必须删除一些字符,否则会允许某些字符以非转义方式通过(例如+)。见https://***.com/a/35912606/1271826。

或者您可以使用像Alamofire 这样的框架来为您处理这些细节。

【讨论】:

【参考方案2】:

在我的例子中,即使是下面的代码也通过在输出的开头附加额外的//斜杠导致了这个错误。

$arr = array("status" => 1, "msg" => "Your message goes here!");
echo json_encode($arr);

原因是这些额外的字符被打印在我包含在此文件中的其他文件中。

【讨论】:

以上是关于错误域 = NSCocoaErrorDomain 代码 = 3840 “JSON 文本不是以数组或对象开头的主要内容,如果未能解决你的问题,请参考以下文章

Json 错误:错误域 = NSCocoaErrorDomain 代码 = 3840“无值”。 UserInfo=NSDebugDescription=无值。

错误域 = NSCocoaErrorDomain 代码 = 3840 “字符周围的值无效

iOS swift 中的错误域 = NSCocoaErrorDomain 代码 = 3840?

iOS:- 错误:无法创建存储目录。错误域 = NSCocoaErrorDomain 代码 = 512

如何修复“错误域 = NSCocoaErrorDomain 代码 = 3840”无价值。“UserInfo = NSDebugDescription = 无价值。”

错误域=NSCocoaErrorDomain 代码=3840 JSONObject