我有一个服务器端Python脚本,它返回一个包含客户端JavaScript参数的JSON字符串。
# Python
import simplejson as json
def server_script()
params = {'formatting_function': 'foobarfun'}
return json.dumps(params)
这个foobarfun
应该引用一个JavaScript函数。这是我的主要客户端脚本
// JavaScript
function client_script() {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, async=true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
options = JSON.parse(xhr.responseText);
options.formatting_function();
}
};
xhr.send(null);
}
function foobarfun() {
//do_something_funny_here...
}
当然,options.formatting_function()
会抱怨“字符串是不可调用的”或类似的东西。
在使用Chrome的Inspect元素时,在Resources选项卡下,并为XHR > query导航左边的侧边栏,我发现client_script
将options
解释如下。foobarfun
被看作是字符串。
// JavaScript
options = {"formatting_function": "foobarfun"}
我希望client_script
能把options
看作
// JavaScript
options = {"formatting function": foobarfun}
当然,在Python中执行以下操作会让它抱怨它对foobarfun
一无所知
# Python
params = {'formatting_function': foobarfun}
问题:
我应该如何从服务器端准备JSON字符串,以便客户端脚本能够正确地解释它?在本例中,我希望foobarfun
被解释为函数对象,而不是字符串。
或者是我应该在客户端做些什么?
发布于 2011-08-21 02:45:54
在JSON中无法获得所需的结果,因为JSON没有函数的概念,它纯粹是一种数据表示法。但有些事你可以在客户端做。
如果您的foobarfun
函数是一个全局函数(我建议反对),那么您可以这样称呼它:
window[options.formatting_function]();
这是因为全局函数是window
对象的属性,您可以使用虚线表示法和文字(window.foobarfun
)或使用括号内的符号和字符串(window["foobarfun"]
)来访问属性。当然,在后一种情况下,字符串不必是字符串文字,它可以是来自属性的字符串--例如,您的options.formatting_function
属性。
但是我不建议使用全局函数,window
对象已经非常拥挤了。相反,我将我的所有函数(在某些边缘情况下尽可能多)保留在主作用域函数中,这样我就不会向全局命名空间添加任何内容:
(function() {
function foobarfun() {
}
})();
现在,如果这样做,您就不能在window
上访问window
,因为这样做的全部目的是避免将它放在window
上。相反,您可以创建自己的对象并使其成为该对象的属性:
(function() {
var myStuff = {};
myStuff.foobarfun = foobarfun;
function foobarfun() {
}
function client_script() {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, async=true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
options = JSON.parse(xhr.responseText);
myStuff[options.formatting_function](); // <== using it
}
};
xhr.send(null);
}
})();
通常,而不是这样:
myStuff.foobarfun = foobarfun;
function foobarfun() {
}
你会看到人们写道:
myStuff.foobarfun = function() {
};
我也不建议这样做,因为您的函数是匿名的(引用该函数的myStuff
上的属性有一个名称,但该函数没有)。给函数命名是一件好事,它是帮助你的工具帮助你 (在调用堆栈、错误消息等中显示名称)。
你可能还会看到:
myStuff.foobarfun = function foobarfun() {
};
这应该是有效的,它是正确的JavaScript。但不幸的是,各种JavaScript实现都有不同的But (称为命名函数表达式),尤其是在IE9之前的Internet,它将在两次不同的时间创建两个完全不同的函数。
所有这些都表明,在客户机和服务器之间传递函数的名称通常意味着您想退一步,再次查看设计。数据应该驱动逻辑,但不是以这样的字面方式。尽管如此,确实有一些有效的用例来执行此操作,您很可能在您的情况下有一个用例。
发布于 2011-08-21 02:47:07
这个问题似乎对你有帮助:
我想我要做的是将对这些方法的引用存储在一个对象文本中,然后通过属性访问它们。
例如,如果我想调用foobarfun
,以及其他函数
var my_functions = {
foobarfun: function(){
},
...
};
...
var my_fn = my_functions[options.formatting_function];
my_fn();
发布于 2011-08-21 03:17:55
可以认为返回字符串为javascript而不是json,通过设置MIME类型text/javascript
https://stackoverflow.com/questions/7137731
复制