【问题标题】:Parse HTTP Response that Contains Serialized Object with Functions使用函数解析包含序列化对象的 HTTP 响应
【发布时间】:2016-12-05 20:01:20
【问题描述】:

我有一个简单的 javascript/jquery 代码,它从某个 Web 服务请求数据,该服务返回可用于创建 highcharts 条形图的数据。来自服务器的响应无法解析为 JSON,因为它包含一个单击事件处理程序,JSON.parse 无法解析该处理程序,错误为 Unexpected keyword ....

javascript 代码如下所示

$.ajax({
    type:"POST",
    url:"service/call"
}).done(function( xdata ) {
  // this is not going to work as xdata is not object but plain text
  $('#container').highcharts(xdata);
});

服务器的响应是这样的

{
 "chart" : {
   "type" : "bar"
 },
 "series" : [ {
   "data" : [ 25, 10 ]
 } ],
 "title" : {
   "text" : ""
 },
 "xAxis" : [ {
   "categories" : [ "data1", "data2"],
  "allowDecimals" : false
 } ],
 "yAxis" : [ {
   "title" : {
     "align" : "high",
     "text" : "Some Title"
   },
   "allowDecimals" : false,
   "labels" : {
     "overflow" : "justify"
   },
   "min" : 0
 } ],
 "credits" : {
   "enabled" : false
 },
 "plotOptions" : {
   "bar" : {
     "colors" : [ "#87bdee", "#ffcccc"],
     "colorByPoint" : true,
     "dataLabels" : {
       "enabled" : true
     },
  "point" : {
       "events" : {
         "click" : function(){window.location.href = '/data?type=' + (this.x == 0 ? 'data1' : (this.x == 1 ? 'hold' : (this.x == 2 ? 'data2' : (this.x == 3 ? 'data3' : (this.x == 4 ? 'data4' : (this.x == 5 ? 'data5' : (this.x == 6 ? 'data6' : 'data7')))))) )}
       }
     }
   }
 },
 "tooltip" : {
   "valueSuffix" : " elements"
 },
 "creditOptions" : {
   "enabled" : false
 }
}

我可以访问服务器端和客户端代码。

那么有没有一种简单的方法可以让事情顺利进行?我的意思是如何在不更改响应的情况下创建高图?

【问题讨论】:

  • 它试图将响应解析为 JSON,但它是 not JSON。您返回 JSON。 JSON is a specific format 仅支持字符串、数字、对象、数组、布尔值和 null。 JSON 文件/字符串中不能有 function
  • 您可以尝试将函数转换为字符串,然后使用eval()Function将函数解析为字符串
  • JSON 中不能有函数,它纯粹是一种数据格式。您可以有一个字符串并在其上运行 EVAL,或者只使用函数名称和参数(即保留已在客户端上定义的函数,只需提供参数)
  • @RocketHazmat 是的,我知道,所以我想知道是否有一种简单的方法可以使用我从服务器获得的响应来创建图表 :)
  • 更新了问题,只是删除了所有关于 JSON 的东西,所以我有一个服务可以返回一些需要用来创建高图的数据...

标签: javascript jquery json ajax highcharts


【解决方案1】:

【讨论】:

  • 我实际上对这个答案非常矛盾。一方面,您的声誉是我的 6 倍,所以我觉得您最了解,另一方面,这种解决方案似乎是癌症。所以你动态地创建函数并给它们它们的身体?再次,您的分数是我的 6 倍,但是这有任何 XSS 问题吗?如果不是,那我很遗憾我没有想到这一点。
  • 这是一个糟糕的 hack,但它是一个糟糕的 hack,它可以满足 Babl 的要求。我想不出更好的方法。
  • @bassxzero 在所有现代浏览器中内置的 JSON 对象中,执行我所展示的操作的能力是标准的。我不会就“您是否应该通过 HTTP 传递函数并在 Web 客户端中使用它们”提供任何评论。我正在为您的问题提供完全合法和有效的答案。顺便说一句,这个解决方案比 eval() 好 10 倍(正如其他人所建议的那样),因为在这里,您控制了 reviver 功能,因此您可以根据自己的逻辑将其清除为恶意内容。
  • 我喜欢@ScottMarcus 解决方案的地方是它不需要更改服务器端。
  • @Babl 嗯,确实如此。字符串化发生在服务器上,因此JSON.stringify(obj, replacer) 需要在服务器上。
【解决方案2】:

这是我过去所做的。

<script type="text/javascript">

   function highChartOnClick() {
       alert('the click worked');
       window.location.href = '/data?type=' + (this.x == 0 ? 'data1' : (this.x == 1 ? 'hold' : (this.x == 2 ? 'data2' : (this.x == 3 ? 'data3' : (this.x == 4 ? 'data4' : (this.x == 5 ? 'data5' : (this.x == 6 ? 'data6' : 'data7')))))) );
   }

    $.ajax({
        type:"POST",
        url:"service/call"
    }).done(function( xdata ) {
         var someConfigurationJSONObject = xdata;
        someConfigurationJSONObject['plotOptions']['bar']['point']['events']['click'] = highChartOnClick;

         $('#container').highcharts(someConfigurationJSONObject);
    });
</script>

【讨论】:

  • 这个解决方案很好,在客户端你肯定知道函数应该做什么,但在我的情况下,函数是在服务器端自动生成的,所以没有办法有类似的东西这。而且我不能创建一个单独的 Web 服务调用来获取这些功能....但无论如何感谢您的帮助 ....
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 2019-08-29
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多