【问题标题】:Send array with GET Request使用 GET 请求发送数组
【发布时间】:2015-08-10 23:43:38
【问题描述】:

我正在向 Python 发送获取请求表单 Javascript。我正在尝试传递一个二维数组,比如

[["one", "two"],["foo", "bar"]]

这是我目前正在尝试的,但它不起作用。

所以在我的 javascript 中,我有一个与上面类似的数组,然后像这样传递它

var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://192.67.64.41/cgi-bin/hi.py?array=" + myArray, false );
xmlHttp.send( null );

然后在 python 中我得到它是这样的

import cgi
form = cgi.FieldStorage()
array = form.getvalue("array")

但结果不正确,如果我这样做的话,在 python 中

print array[0]
#I get -> "o"
print array[1]
#I get -> "n"
print array[2]
#I get -> "e"

等等,但如果我想要的是

print array[0]
#output -> ["one", "two"]

我怎样才能做到这一点?

谢谢

【问题讨论】:

  • 你能改变你在 python 中接收数据的方式吗?最好更改您的请求以从正文中读取数据。
  • @MarkoGrešak 是的,我可以更改它我只是不确定将其更改为什么?但如果你能告诉我一个更好的方法将数据从 javascript 发送到 pythonn 那会很棒
  • This answer 可能是一个开始,您发送一个 POST 请求并将您的数据作为 javascript 请求正文。如果您使用像jQuery 这样的库,这对您来说会容易得多,其中XMLHttpRequests 与$.ajax 一起轻而易举。对于后端框架,请选择 python 网页上列出的web frameworks 之一。在任何严肃的工作中,您都需要这些来提高工作效率。
  • @MarkoGrešak 是的,但我仍然如何传递二维数组?
  • 您可能必须在发送之前使用JSON.stringify 将其转换为json,然后在您的python 代码中将其解析回。但我相信 jQuery 的 $.ajax({url: 'http://192.67.64.41/cgi-bin/hi.py', data: myArray }) 会自动执行此操作。

标签: javascript python arrays http get


【解决方案1】:

您不能简单地将数组作为查询参数传递。您将需要遍历数组并将其添加到 URL 字符串中,例如 ?array[]=one&array[]=two

这里以基本的jsfiddle为例

var a=['one', 'two'];
var url = 'www.google.com';

for (var i=0; i<a.length; ++i) {
    if (url.indexOf('?') === -1) {
        url = url + '?array[]=' + a[i];  
    }else {
        url = url + '&array[]=' + a[i];
    }
}

console.log(url);

【讨论】:

  • 所以我必须分别传递每个字符串?也喜欢?array[]=one&amp;array[]=two&amp;array[]=foo&amp;array[]=bar?但是然后会在python中的数组中吗?
  • 您将能够通过键访问 GET 值,因此 array[0] 将等于 one
  • 好的,只是为了澄清array[2] 会是 foo 吗?有没有办法让它成为一个二维数组?
  • 您可以通过简单地构建查询字符串来做到这一点,这样查询字符串就会显示为array[][]=bar。这将返回为array[0][0]
  • @carl-markham :你还记得查询字符串不是无限的吗?您的建议会起作用,但是,嗯,我宁愿直接解决问题,也不愿屈服于阵列。
【解决方案2】:

不,您不必这样做。而且,是的,你可以做到这一点!您可以像以前一样将它作为一个字符串传递,然后获取它并在 Python 中对其进行评估。

你可以使用:

evaldict = {}
array = eval("[[1, 2, 3], [4, 5, 6]]", evaldict)

虽然我强制将评估范围封装在一个字典中,但这并不安全!

因为有人可以传递一些其他 Python 表达式来进行评估。因此最好使用不评估表达式的 ast 模块中的 literal_eval()。

我建议你使用 jquery 及其 post() 方法来执行此操作,使用 POST HTTP 方法而不是 GET。

此外,使用 json 可以很好且安全地完成此操作(发送 json 而不是手动对 JS 数组进行字符串化。 并使用它来避免直接评估列表(在 Python 中)。

这里是使用 jquery 的客户端:

<html><head><title>TEST</title>
<script type="text/javascript" src="jquery.js"></script>
<script>

pyurl = "http://example.com/cgi-bin/so.py";
function callpy (argdict) {
    $.post(pyurl, argdict, function (data) {    
    // Here comes whatever you'll do with the Python's output.
    // For example:
    document.getElementById("blah").innerHTML = data;
    }, "text");
};

var myArray = [["one", "two"], ["foo", "bar"]];
// This is array shape dependent:
function stringify (a) {
    return "['" + a.join("', '") + "']";
    };
myArrayStr = "[";
for (x = 0; x<myArray.length; x++) {
    myArrayStr += stringify(myArray[x]) +", ";
    }
myArrayStr += "]";
// This would be better, but it is library dependent:
//myArrayStr = JSON.stringify(myArray);
</script>
</head><body>
<a href="#" onclick="javascript:callpy({'array': myArrayStr});">Click me!</a>
<p id="blah">
Something will appear here!
</p>
</body></html>

这是服务器端 CGI:

#! /usr/bin/env python
try:
    # This version of eval() ensures only datatypes are evaluated
    # and no expressions. Safe version of eval() although slower. It is available in Python 2.6 and later
    from ast import literal_eval as eval
except ImportError:
    import sys
    print "Content-Type: text/html\n"
    print "<h1>literal_eval() not available!</h1>"
    sys.exit()
import cgi, cgitb
import sys
cgitb.enable()

print "Content-Type: text/html\n"

i = cgi.FieldStorage()
q = i["array"].value.strip()
print "I received:<br>"
print q
# Put here something to eliminate eventual malicious code from q
# Check whether we received a list:
if not q.startswith("[") and not q.endswith("]"):
    print "Wrong query!"
    sys.exit()

try: myArray = eval(q)
except: print "Wrong query!"; sys.exit()
if not isinstance(myArray, list):
    print "Wrong query!"
    sys.exit()
print "<br>Evaluated as:<br>"
print myArray

现在,注意两边都使用 json 会更快更灵活。

【讨论】:

  • 您是否介意提供更多信息,因为我不确定如何执行您所描述的内容
  • 是的,但请给我一些时间。我只是想让你知道这是可能的,而且还很容易。我以前做过。我很快就会编辑我的帖子。
  • 太好了,只要有时间就好 :),顺便说一句,我不担心安全性,因为这只是临时情况,但如果 POST 仍然比一切都好
  • POST 肯定更好,不包括安全性。因为您不必担心转义字符等,您只需发送一个原始二进制数据,该数据可以任意大(嗯,网络服务器允许的大)。
  • 好的 POST 就是这样,当你更新你的答案时告诉我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2018-01-27
  • 2016-04-18
  • 1970-01-01
相关资源
最近更新 更多