一、问题描述

这周搬砖的时候,前端通过ajax获取后端的数据后,照例用 对象.属性 的方式取值,然而结果总是总是不能如预期般展示在页面上。

先写个 demo 还原下场景:选中一个下拉框列表选项后,会在下拉框下面展示文字。

这是下拉框的html部分:

<html>
<head>
<title>JSON DEMO</title>
<meta charset="UTF-8">
</head>
<body>
<select id="device">
<option value="">终端设备</option>
<option value="1">PC Web</option>
<!-- <option>...</option> -->
</select>
<div id="tip"></div>
</body>
</html>

PHP代码如下:用来返回数据(接收、处理过程略)

<?php
$onLines = [
1 => 'PC Web',
2 => 'iPad HD',
5 => 'Touch'
];
echo json_encode(['data' => $onLines]);

JS代码如下:

<script type="text/javascript">
$("#device").change(function() {
var selectVal = $("#device").val();
if (selectVal == '') {
$("#tip").html('');
return;
}
# code... ajax 部分的代码见下
});
</script>

ajax 部分的代码用来接收从后端(PHP)传过来的数据,并处理。

$.ajax({
url: 'device.php',
type: 'post',
dateType: 'json',
data: {
device: selectVal
},
success: function(result) {
var onlineDevices = result.data;
var onlineTip = '允许' + onlineDevices[selectVal] + '类型的2台设备同时在线。'; $("#tip").html('');
$("#tip").append(onlineTip);
}
});

使用 console.log 在控制台输出结果,如下图所示,可以看到后端返回的数据是没有问题的,

再使用 typeof 查看返回的数据类型,前端收到的数据是JSON字符串!而不是JSON对象!

success: function(result) {
console.log(result);
console.log(result.data);
console.log(typeof result);
}

二、解决方法

找到问题就好办了,只需要把 json 字符串转成 json 对象就好了,最简单的办法是 JSON.parse()

success: function(result) {
var onlineDevices = JSON.parse(result).data;
# code ...
}

三、总结

1、json字符串和json对象的区别

// JSON 字符串
var str1 = '{"data":{"1":"PC Web","2":"iPad HD","5":"Touch"}}';
// JSON 对象
var str2 = {"data":{"1":"PC Web","2":"iPad HD","5":"Touch"}};
console.log(str1);
console.log(typeof str1);
console.log(str2);
console.log(typeof str2);

可以看到json字符串和json对象的形式很像,但前者比后者多了一对引号,其内容包含在引号里了。调试台的结果如下:

2、json字符串转为json对象的方法

后端

  • 设置header头中的内容类型,将 Content-Type 设置为 text/json。

    header('Content-Type:text/json;charset=utf-8');

    注:前端直接处理即可,不需要 JSON.parse() 处理。

    但项目中用的是框架,所有的PHP文件(业务层)均没有显式设置 header,虽然在demo中此方法有效,可依然不明白为什么别的地方返回的是json对象,而这里返回的却是json字符串了。

  • 强制类型转换(object) 此方法无效!

    如果将一个对象转换成对象,它将不会有任何变化。如果其它任何类型的值被转换成对象,内置标准类 stdClass 的一个实例将被建立。

    以上面的数组为例,强制类型转换的结果如下:

var_dump((object)['data' => $onLines]);
// 结果如下:
object(stdClass)#1 (1) {
["data"]=>
array(3) {
[1]=>
string(6) "PC Web"
[2]=>
string(7) "iPad HD"
[5]=>
string(5) "Touch"
}
}

json_encode((object)['data' => $onLines]);得到的还是json字符串。

前端

  • var obj = JSON.parse(str);

    JSON.parse()方法,必须保证传入的是json字符串,如果是json对象会报错。

  • var obj = jQuery.parseJSON(str);

    parseJSON()方法是jQuery方法,仅支持标准json格式,否则会报错。

    下面这些是无效的 JSON 字符串:
"{test: 1}"
//test是属性名称,必须加双引号 "{'test': 1}"
//test是属性名称,必须用双引号(不能用单引号) "'test'"
//test是属性名称,必须用双引号(不能用单引号) "undefined"
//undefined 不能表示一个 JSON 字符串; null可以 "NaN"
//NaN 不能表示一个 JSON 字符串; 用Infinity直接表示无限也是不允许的

  • var obj = eval('(' + str + ')');

    eval()方法是js方法,也是必须保证传入的是json字符串,否则会报错。

四、疑惑

查了一下PHP的 json_encode()函数,PHP手册给出的结论是成功时返回字符串

Return Values

Returns a JSON encoded string on success or FALSE on failure.

既然json_encode()函数返回的是字符串,为什么在项目中其他地方可以直接使用 对象.属性 的方式呢?

后记 更新于2019-02-25

今天不死心,又研究了一下,还问了一个朋友,对方提醒估计大概率是编码和头的设置有问题,然后我逐行查代码,发现 ajax 部分的dataType我写成了dateType,一字之差~

噢,天啊,太丢人了!以后绝对不能再犯这么的错误了!

PHP的json_encode()函数与JSON对象的更多相关文章

  1. eval() 函数 解析json对象

    eval在js中用来运行以js源码组成的字符串. 可以用来改变全局或者局部变量,例如: var globalEval = eval; //定义全局eval函数别名 var a ='global', b ...

  2. json对象之间的转化

    json字符串转化为 1.使用JSON.parse()函数 使用eval()函数 2.json对象转化为json字符串 使用JSON.stringify()

  3. PHP中json_encode()使用须知,JSON数组和JSON对象

    ⊰ 偷偷的告诉你,这是一个很不谨慎就会踩得坑 ⊱  如下代码 (看了一下很简单,没毛病啊,老铁) $arr = array( '0'=>'a','1'=>'b','2'=>'c',' ...

  4. php json_encode()函数返回对象和数组问题

    php json_encode() 函数格式化数据时会根据不同的数组类型格式化不同类型的json数据 索引数组时 <?php $arr = [1,2,3,4,5]; print_r(json_e ...

  5. js学习-自定义函数、对象的字面量、json对象学习小结

    一.自定义对象的构造: var student=new Object(); //object是顶级对象,使用构造函数的方法创建一个对象,此处的意思是创建了一个学生的空对象 student.name=& ...

  6. Js对象转String的函数 和 JSON转String

    js对象转string的函数 function obj2str(o){ var r = []; if(typeof o =="string") return "" ...

  7. 关于JSON对象,以及联合数组,eval函数的使用参考

    关于JSON对象,以及联合数组,eval函数的使用参考 var json="{persons:[{name:'Zhangsan',sex:'male'},{name:'Lisi',sex:' ...

  8. 关于json_encode转数组为json对象时里有数组格式数据的问题

    前言:这次是给一款小程序提供接口时发现的 别的不多说,下面直接看出现问题的json数据 可以看到,这是一个大的json对象,是由多维数组组成,一般api接口提供的也是这种格式. 但是仔细看红框中的内容 ...

  9. JSON对象和JSON字符串以及JSON.parse 函数的使用

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. vim基本命令总结

    编辑模式下i 从光标所在位置前开始插入文本I 将光标移动到当前行行首,然后在其前插入文本a 用于在光标当前所在位置之后追加新文本A 将光标移动到所在行行尾,在那里插入新文本o 在光标所在行的下面新开一 ...

  2. pandas的基本功能(一)

    第16天pandas的基本功能(一) 灵活的二进制操作 体现在2个方面 支持一维和二维之间的广播 支持缺失值数据处理 四则运算支持广播 +add - sub *mul /div divmod()分区和 ...

  3. react中对于redux的封装

    const createStore = (reducer)=>{ //默认的state对象 let state = {}; //将所有订阅的事件存在在这个数组中 let listeners = ...

  4. 小容量的byteBuffer 读取大文本

    利用死循环和判断是否 读到0个字节,便能判断是否读取完成,但它存在如下问题,如果输入是中文的话,可能没有读取完中文的全部3个字节,导致乱码.如果数据足够随机,这样的情况肯定会出现的 @Test pub ...

  5. IIS的地址指向

    地址指向 1)AuthwebAPI  修改web.xml文件 <connectionStrings> data source 改成当前虚拟环境的IP指向 </connectionSt ...

  6. ElasticSearch(十)Elasticsearch检索出的数据列表按字段匹配的优先顺序及搜索单词拼音一部分搜不到数据

    检索出的数据列表按字段匹配的优先顺序 一.举例 比如,发布一篇文章,文章包括基本的字段包括标题.发布时间.点击率.关键字.内容.当在页面中输入“教育”搜索关键词,会检索出指定字段包括“教育”的所有数据 ...

  7. C语言解析WAV音频文件

    C语言解析WAV音频文件 代码地址: Github : https://github.com/CasterWx/c-wave-master 目录 前言 了解WAV音频文件 什么是二进制文件 WAV的二 ...

  8. android架构原理

    应用层(与用户打交道) 应用架构层(常用的组件和服务) 系统运行层(Android运行环境+原生c/c++库) Linux核心层(linux内核+硬件抽象层)

  9. 问题:Linux报swap空间占用过高,但物理内存还有空余

    报错 收到报警,swap空间占用过高,登录到系统查看内存使用详情,看到物理内存还有很多未使用 问题分析 Swap配置对性能的影响分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统会发生错 ...

  10. asp.net 对象转XML,XML转对象

    //对象转XML public static string ObjToXml(object obj) { using (MemoryStream Stream = new MemoryStream() ...