通过Javascript Remoting在Visualforce页面展示JSON内容时遇意外令牌错误
嘿,这个问题我之前做Visualforce项目的时候也踩过坑!大概率是JSON的转义或者序列化环节出了问题,咱们一步步拆解解决:
常见原因及修复方案
1. Apex方法手动拼接JSON导致语法错误
很多新手会犯的错:手动拼接JSON字符串,很容易遗漏引号、转义特殊字符,导致最终的JSON格式无效。
正确做法:永远用Salesforce自带的JSON.serialize()方法序列化数据,不要手动拼接:
public with sharing class CustomObjectExtension { public String jsonResult {get; set;} public void getCustomObjectData() { // 查询自定义对象数据 List<Custom_Object__c> targetRecords = [SELECT Id, Name, Custom_Field__c FROM Custom_Object__c LIMIT 10]; // 自动序列化,保证JSON格式绝对正确 jsonResult = JSON.serialize(targetRecords); } }
2. Visualforce自动转义JSON特殊字符
如果你的页面是把Apex返回的JSON绑定到页面元素(比如隐藏的outputText),Visualforce默认会转义HTML特殊字符(比如双引号"变成"),这会直接导致JSON.parse()抛出"Unexpected token"错误。
修复方法:在绑定数据时添加escape="false"属性,禁止转义:
<apex:page standardController="Custom_Object__c" extensions="CustomObjectExtension"> <apex:form> <apex:actionFunction name="fetchData" action="{!getCustomObjectData}" rerender="jsonContainer"/> <button onclick="fetchData(); return false;">加载自定义对象数据</button> <!-- 核心:escape="false"避免JSON被转义 --> <apex:outputText id="jsonContainer" value="{!jsonResult}" escape="false" style="display:none;"/> </apex:form> <script> function renderData() { var rawJson = document.getElementById('jsonContainer').textContent; try { var parsedData = JSON.parse(rawJson); console.log('解析成功:', parsedData); // 把数据渲染到页面示例 var outputDiv = document.createElement('div'); outputDiv.innerHTML = '<h3>自定义对象数据</h3><pre>' + JSON.stringify(parsedData, null, 2) + '</pre>'; document.body.appendChild(outputDiv); } catch (e) { console.error('JSON解析错误:', e.message); alert('数据加载失败:' + e.message); } } // 监听rerender完成事件,确保数据已更新 document.getElementById('jsonContainer').addEventListener('DOMSubtreeModified', function() { if (this.textContent) { renderData(); // 只执行一次,避免重复触发 this.removeEventListener('DOMSubtreeModified', arguments.callee); } }); </script> </apex:page>
3. 改用@RemoteAction(更简洁推荐)
其实用Visualforce Remote Action可以跳过rerender和转义的麻烦,直接让Apex返回JSON给JS,代码更简洁,出错概率更低:
Apex控制器扩展代码
public with sharing class CustomObjectExtension { // 标准控制器构造方法 public CustomObjectExtension(ApexPages.StandardController stdController) {} @RemoteAction public static List<Custom_Object__c> getCustomObjectData() { // 直接返回SObject列表,Salesforce会自动序列化为合法JSON return [SELECT Id, Name, Custom_Field__c FROM Custom_Object__c LIMIT 10]; } }
Visualforce页面代码
<apex:page standardController="Custom_Object__c" extensions="CustomObjectExtension"> <button onclick="fetchRemoteData(); return false;">加载自定义对象数据</button> <script> function fetchRemoteData() { CustomObjectExtension.getCustomObjectData( function(result, event) { if (event.status) { console.log('数据加载成功:', result); // 渲染数据到页面示例 var outputDiv = document.createElement('div'); outputDiv.innerHTML = '<h3>自定义对象数据</h3><pre>' + JSON.stringify(result, null, 2) + '</pre>'; document.body.appendChild(outputDiv); } else { console.error('请求失败:', event.message); alert('数据加载失败:' + event.message); } }, {escape: false} // 确保返回的JSON不被转义 ); } </script> </apex:page>
4. 快速调试技巧
如果还是出错,先把拿到的原始字符串打印出来看看:
console.log('拿到的原始字符串:', rawJson);
检查是不是有多余的空格、换行,或者被转义的符号(比如"),这样能快速定位问题根源。
内容的提问来源于stack exchange,提问作者Rudy
相关产品推荐
相关产品推荐

