Это как использовать хеши с JSON? - PullRequest
4 голосов
/ 16 мая 2011

Я создаю веб-страницу, на которой есть две формы (пользователи и владельцы), где можно вводить имена, разделенные запятыми, в каждой форме и нажимать «Отправить».

Ранее я пытался использовать JSON только со строками, без использования модуля Perl. Теперь мне нужно передать информацию для многих пользователей в виде username, full name и owner_name, full name. В Perl это два хеша.

Это вопрос из двух частей.

Серверная часть

Это мой Perl-скрипт.

#!/usr/bin/perl -T

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard);
use JSON;
use utf8;
use strict;
use warnings;

my $cgi = CGI->new;
$cgi->charset('UTF-8');

my @owners = map { s/\s*//g; $_ } split ",", $cgi->param('owner');
my @users  = map { s/\s*//g; $_ } split ",", $cgi->param('users');

# ...

my %user_result = ();
foreach my $u (@users) {
    $user_result{$u} = $db1->{$u}{displayName};
}

my %owner_result = ();
foreach my $o (@owners) {
    $owner_result{$o} = $db2{$o}{ad_displayname};
}

my $json->{"users"}  = \%user_result;
my $json->{"owners"} = \%owner_result;

my $json_string = to_json($json);

print $cgi->header(-type => "application/json", -charset => "utf-8");
print $json_string;

Это правильный способ сделать два хэша в строку JSON?

Клиентская сторона

$(document).ready(function(){
    $('form').live('submit', function(){
    $.ajax({
        type: "GET",
        url: "/cgi-bin/ajax.pl",
        contentType: "application/json; charset=utf-8",
        dataType: "json",

        data: $(this).serialize(),

        error: function(XMLHttpRequest, textStatus, errorThrown) { 
        $('div#create_result').text("responseText: " + XMLHttpRequest.responseText +
                        ", textStatus: " + textStatus +
                        ", errorThrown: " + errorThrown);
        $('div#create_result').addClass("error");
        },

        success: function(result){
        if (result.error) {
            $('div#create_result').text("result.error: " + result.error);
            $('div#create_result').addClass("error");
        } else { // perl script says everything is okay

              // how do I access my two hashes here?
              // {"users": [username1, fullname1, ...], "owners": [owner name1, full name 1, ...]}

              var users  = result.users;    // array
              var owners = result.owners;   // array
              alert(users);
              alert(owners);

        }
        }
    });
    });
});

Это правильный способ отправки и получения JSON?

А как мне получить доступ к данным после этого?

Обновление Обновлен код с ответами Мэтта Болла и Даворга и добавлено alert(users).

Ошибка сейчас в том, что объект json не определен.

my $json->{"users"}  = \%user_result;
my $json->{"owners"} = \%owner_result;

Как мне определить такое?

Ответы [ 2 ]

5 голосов
/ 16 мая 2011

Вы пытаетесь напечатать два блока заголовка CGI. К сожалению, вы можете иметь только один блок CGI, связанный с каждым ответом. И, к сожалению, первый напечатанный вами блок заголовка имеет неправильный заголовок типа контента (это «text / html», где вы на самом деле хотите «application / json»).

Если вы удалите строку 'print "Content-Type: ...", все должно работать немного лучше.

Затем во втором блоке заголовка вы пытаетесь вызвать неизвестную функцию с именем «заголовок». На самом деле это метод для вашего объекта $ cgi, поэтому его нужно вызывать как $ cgi-> header (...).

Эти исправления на самом деле должны успешно вернуть JSON в ваш клиентский код. Однако я бы сделал несколько других предложений.

1 / Первый аргумент функции split должен быть регулярным выражением, а не строкой.

2 / Структуры данных JSON, которые вы строите, кажутся излишне сложными. Для каждого из ваших двух разделов (пользователей и владельцев) у вас есть отдельный массив элементов, который содержит ссылку на хеш. Конечно, массив может быть опущен, так что каждый элемент просто содержит ссылку на хеш напрямую.

4 голосов
/ 16 мая 2011

При dataType: 'json' jQuery автоматически проанализирует результат JSON для вас. Это означает, что значение result, переданное в обратный вызов success, уже является правильным объектом JavaScript. Вы можете обращаться к его значениям так же, как и к любому другому объекту JS. Например, если скрипт Perl возвращает этот JSON:

{"foo": "a", "bar": 42, "baz": [true, false]}

Затем вы можете получить доступ к различным полям в обратном вызове success следующим образом:

success: function(result) {
    var foo = result.foo,    // 'a'
        bar = result.bar,    // 42
        baz = result.baz;    // [true, false]
}

Если вы установите Content-Type: application/json в заголовке ответа (в Perl), вам даже не понадобится dataType: 'json', поскольку jQuery может прослушивать тип данных из заголовка HTTP Content-Type.

Я не знаю Perl, поэтому я не могу помочь вам на этой стороне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...