JSON解析错误语法错误意外结束输入

Posted

技术标签:

【中文标题】JSON解析错误语法错误意外结束输入【英文标题】:JSON parsing error syntax error unexpected end of input 【发布时间】:2014-01-16 14:53:25 【问题描述】:

我得到以下代码

function pushJsonData(productName) 
    $.ajax(
        url: "/knockout/SaveProduct",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: "  \"Name\" : \"AA\"  ",
        async: false,
        success: function () 
            loadJsonData();   
        ,
        error: function (jqXHR, textStatus, errorThrown) 
          alert(textStatus + " in pushJsonData: " + errorThrown + " " + jqXHR);
        
    );

请注意,我对数据值进行了硬编码。数据被很好地推入数据库。但是,我不断收到错误

解析错误语法错误意外结束输入

我确信我的数据是正确的 JSON 语法。当我在 Chrome 网络检查器上检查时,saveProduct 请求显示数据是正确的。

 "Name": "AA" 

此 POST 请求没有响应。所以我对解析错误的来源一无所知。我尝试使用 FireFox 浏览器。同样的事情发生了。

谁能给出一些关于哪里出了问题的想法?

谢谢,

附: 这是控制器代码

namespace MvcApplJSON.Controllers

    public class KnockoutController : Controller
    
        //
        // GET: /Knockout/

        public ActionResult Index()
        
            return View();
        

        [HttpGet]
        public JsonResult GetProductList()
        
            var model = new List<Product>();
            try
            
                using (var db = new KOEntities())
                
                    var product = from p in db.Products orderby p.Name select p;
                    model = product.ToList();
                
            
            catch (Exception ex)
             throw ex; 
            return Json(model, JsonRequestBehavior.AllowGet);
        
        [HttpPost]
        public void SaveProduct (Product product)
        
            using (var db = new KOEntities())
            
                db.Products.Add(new Product  Name = product.Name, DateCreated = DateTime.Now );
                db.SaveChanges();
            
        
    

【问题讨论】:

" \"Name\" : \"AA\" " -> " 'Name' : 'AA' " 在 json 对象中 "' 之间存在差异 是的,您的第二个示例生成无效的 JSON。单引号不是有效的 JSON! @DarinDimitrov 这也适用于我所看到的(您可以在 jsonviewer.stack.hu 上尝试),但您不能将字符串作为对象发送(如果您没有该对象字符串名称可用)。所以最后:你是对的 这个错误出现在客户端还是服务器端? 您刚刚失去了 Internet 连接。就是这样。 【参考方案1】:

我不能确定问题是什么。可能是一些不好的角色,可能是你在开头和结尾留下的空格,不知道。

无论如何,您不应该像以前那样将 JSON 硬编码为字符串。相反,将 JSON 数据发送到服务器的正确方法是使用 JSON 序列化程序:

data: JSON.stringify( name : "AA" ),

现在在服务器上还要确保你有正确的视图模型来接收这个输入:

public class UserViewModel

    public string Name  get; set; 

以及对应的动作:

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)

    ...

现在还有一件事。您已指定dataType: 'json'。这意味着您期望服务器将返回 JSON 结果。控制器操作必须返回 JSON。如果您的控制器操作返回一个视图,这可以解释您遇到的错误。当 jQuery 尝试解析来自服务器的响应时:

[HttpPost]
public ActionResult SaveProduct(UserViewModel model)

    ...
    return Json(new  Foo = "bar" );

话虽如此,在大多数情况下,当向 ASP.NET MVC 控制器操作发出 AJAX 请求时,通常不需要设置 dataType 属性。这样做的原因是因为当你返回一些特定的ActionResult(例如ViewResultJsonResult)时,框架会自动设置正确的Content-Type 响应HTTP 头。然后,jQuery 将使用此标头解析响应并将其作为参数提供给已解析的成功回调。

我怀疑您在这里遇到的问题是您的服务器没有返回有效的 JSON。它要么返回一些 ViewResult 或 PartialViewResult,要么您尝试在控制器操作中手动制作一些损坏的 JSON(显然您不应该这样做,而是使用 JsonResult 代替)。

我刚刚注意到的另一件事:

async: false,

请避免将此属性设置为 false。如果您将此属性设置为false,您将在整个请求执行期间冻结客户端浏览器。在这种情况下,您可以提出一个正常的请求。如果您想使用 AJAX,请从异步事件和回调的角度开始考虑。

【讨论】:

嗨,达林,感谢您的快速回复。我试图将您的代码粘贴到我的代码中,以替换我拥有的代码。但我得到了完全相同的错误。我可以看到数据被推送到数据库中。我可以选择验证。我正在使用带有 knockout.js 的 MS ASP.NET MVC4。可以找出哪个部分在抱怨这个错误。 也许错误在您在success 回调中调用的loadJsonData 函数内部,与AJAX 请求本身无关?您究竟在哪里/何时看到此错误?使用 FireBug 或 Chrome 开发者工具栏的Network 选项卡来检查 AJAX 请求并查看服务器是否返回 JSON 响应。服务器的确切响应是什么?您的 success 回调不接受任何参数。这是为什么?您的 SaveProduct 控制器操作是否返回 JsonResult?我怀疑您将其声明为void。请仔细阅读我的整个答案。 好的,但您没有回答我在上一条评论中的其他问题。我会重复一遍:服务器的确切响应是什么?您的 success 回调不接受任何参数。这是为什么?您的SaveProduct 控制器操作是否返回JsonResult?我怀疑您将其声明为void 哥们,你还在看我的回答吗???我强调的一件事是你的控制器操作应该返回一个JsonResult。不存在返回void 的控制器操作。您已指定 dataType: 'json',因此返回 JSON。而已。至于这个控制器操作应该采用什么参数,那么,从您发送的 JSON ("Name":"AA") 中,它应该是一个具有字符串类型的 Name 属性的类。这一切都已经在我的回答中体现出来了。 请仔细阅读。我在回答中为您提供了解决此问题所需的一切 所以,是的,修改你的动作签名看起来像这样:[HttpPost] public ActionResult SaveProduct (Product product) ... return Json(new success = true ); 。或者,如果您不想返回 JSON,请从您的 AJAX 请求中删除此 dataType: 'json' 属性。在这种情况下,您可以简单地返回状态代码 201(使用空响应正文创建):return new HttpStatusCodeResult(201);【参考方案2】:

我正在使用节点 http 请求并监听 data 事件。该事件只是将数据临时放入缓冲区,因此无法获得完整的 JSON。要解决此问题,必须将每个 data 事件附加到一个变量。可能会帮助某人 (http://nodejs.org/api/http.html)。

【讨论】:

【参考方案3】:

不要返回空 Json

在我的情况下,我在 .Net Core Web API 项目中返回 Empty Json String。

所以我改变了我的代码

来自

 return Ok();

收件人

 return Ok("Done");

看来你必须返回一些字符串或对象。

希望这会有所帮助。

【讨论】:

谢谢,让我来:'return Request.CreateResponse(HttpStatusCode.OK, "Done");'【参考方案4】:

对我来说,问题是由于名称/值对的单引号引起的... 数据:“'Name':'AA'”

一旦我将它更改为名称/值对的双引号,它就可以正常工作... 数据:'“名称”:“AA”' 或者像这样... 数据:"\"姓名\":\"AA\""

【讨论】:

【参考方案5】:

可能会有用。

方法参数名称应该和JSON一样

它会正常工作

C#

public ActionResult GetMTypes(int id)

JS

 var params =  id: modelId  ;
                 var url = '@Url.Action("GetMTypes", "MaintenanceTypes")';
                 $.ajax(
                     type: "POST",
                     url: url,
                     contentType: "application/json; charset=utf-8",
                     dataType: "json",
                     data: JSON.stringify(params),

它不会正常工作

C#

public ActionResult GetMTypes(int modelId)

JS

 var params =  id: modelId  ;
                 var url = '@Url.Action("GetMTypes", "MaintenanceTypes")';
                 $.ajax(
                     type: "POST",
                     url: url,
                     contentType: "application/json; charset=utf-8",
                     dataType: "json",
                     data: JSON.stringify(params),

【讨论】:

【参考方案6】:

输入的意外结束意味着解析器过早结束。例如,它可能期待"abcd...wxyz",但只看到"abcd...wxy

这可能是某处的错字错误,也可能是您在应用程序的不同部分混合编码时遇到的问题。

一个例子:假设您正在使用 chrome.runtime.sendNativeMessage 从本机应用程序接收数据:

chrome.runtime.sendNativeMessage('appname', toJSON:()=>return msg, (data)=>
    console.log(data);
);

现在调用您的回调之前,浏览器将尝试使用JSON.parse 解析消息,如果supplied byte length 与数据不匹配,这可能会给您“输入意外结束”错误.

【讨论】:

【参考方案7】:

我在 Node JS 中做了这个,它解决了这个问题:

var data = JSON.parse(Buffer.concat(arr).toString());

【讨论】:

【参考方案8】:

剧透:可能的服务器端问题

这是我发现的,我的代码期望我的服务器的响应,当服务器只返回 200 个代码时,这还不够来自 json 解析器抛出错误 错误意外结束输入

fetch(url, 
        method: 'POST',
        body: JSON.stringify(json),
        headers: 
          'Content-Type': 'application/json'
        
      )
        .then(res => res.json()) // here is my code waites the responce from the server
        .then((res) => 
          toastr.success('Created Type is sent successfully');
        )
        .catch(err => 
          console.log('Type send failed', err);
          toastr.warning('Type send failed');
        )

【讨论】:

【参考方案9】:

我在将包含 \n 的字符串解析为 JSON 时遇到了同样的错误。解决方案是使用string.replace('\n','\\n')

【讨论】:

【参考方案10】:

在读取空的 JSON 文件时会发生此错误。

为了避免在 NodeJS 中出现这个错误,我正在检查文件的大小:

const  size  = fs.statSync(JSON_FILE);
const content = size ? JSON.parse(fs.readFileSync(JSON_FILE)) : DEFAULT_VALUE;

【讨论】:

以上是关于JSON解析错误语法错误意外结束输入的主要内容,如果未能解决你的问题,请参考以下文章

我在尝试恢复节点模块时收到错误“错误意外结束 JSON 输入时解析'...“依赖项”:“tsli'”[重复]

在“...ge-2.2.1.tgz”,“engin”附近解析时出现错误的 JSON 输入意外结束

创建反应应用程序:npm 错误!在“....”附近解析时 JSON 输入意外结束

通过 npm 安装 firebase 时遇到错误 |在 [关闭] 附近解析时 JSON 输入意外结束

“在附近解析时 JSON 输入意外结束”错误:npm install -g@angular/cli

解析错误:语法错误,文件意外结束,期待'`' [重复]