如何将JSON数据从Perl脚本传递到本地角度控制器

时间:2018-12-05 15:43:38

标签: angular perl http

Tl; dr 我希望能够使用类似 angular的http服务,但都可以在我的机器上本地使用,这样我就不必使用服务器正在运行以使其正常工作。我当前的错误消息是

Access to XMLHttpRequest at 'file:C:/myfilepaths/cgi-bin/movieSearch.pl?movie=Red' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

是否有一种简便的方法可以在本地完成所有操作?

完整的代码示例: 我目前正在尝试构建一个Web应用程序,要求用户输入电影,角度控制器接受此查询并将其传递给Perl脚本,该脚本将抓取imdb以将可能的电影匹配返回给用户输入。我之前已经做过类似的事情,并具有有效的代码: 前端:

<div ng-app="myApp" ng-controller="Ctrl1">

    <p> Input movies : </p>
    <form ng-submit="loadMovie1()">
    Movie 1 : <input type="text" ng-model="movie1">
    <input type="submit" id="submit" value="Submit" />
    </form>

    <p>list={{list}}</p>
</div>

我正在使用Angular的http服务:

$scope.loadMovie1 = function() {
        if($scope.movie1){
        //Take input and call the perl script to scrape imdb                
        var movieList = [];
        $http.get("../cgi-bin/movieSearch.pl",{params: {movie: $scope.movie1}})
        .then(function(response) {
            movieList = response.data.record; 
            console.log(movieList);
            //pass to next function
            }, function (error){
            console.log(error);
            });

        }   
    };

最后,我使用了一个称为Web :: Scraper的perl Web抓取库。抓取效果很好,为简便起见,我将不包括整个perl脚本。足以说出我是从imdb中获取数据,并使用这段perl将其格式化为JSON对象:

package rec;
sub new {
    my $class = shift;
    my $self = {
    text => shift, #Fields returned by the query
    link => shift,
    };
    my $self2 = {
    record => $self #Every SQL Data row will be anchored by 'record' as the root node
    };
    bless $self2, $class;
    return $self2;
}
sub TO_JSON { return { %{ shift() } }; }

package main;
my $json_str = JSON->new->utf8;
$json_str->convert_blessed(1);
my $temp;
my $e;
my $JSON;
my $master_json;
my $final_data = {};
#-----------------------------------------------
# Begin JSON Wizardry
#-----------------------------------------------
foreach my $row (\@returnMatrix)
{
$temp = encode_json(\@$row); # Pull a single row in comma separated format
$e = new rec(split(',',substr($temp, 1, -1))); # Pass the row to the rec class constructor
my $key = (keys %$e)[0]; # Get the key of that row (Will be "record" for every row)
$final_data->{$key} ||= []; # Push key onto final_data
push @{$final_data->{$key}}, $e->{$key};
}

$JSON = $json_str->encode($final_data); # Encode the full JSON object

print "$JSON\n"; #return the json object to the controller.

现在这一切都很好。但是令人遗憾的是,令我沮丧的是,这对我来说不起作用,因为我没有运行服务器,因此angular的http服务返回了错误:

Access to XMLHttpRequest at 'file:C:/myfilepaths/cgi-bin/movieSearch.pl?movie=Red' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

我希望不必一直安装或运行服务器来完成这项工作...我想从我的计算机本地运行所有这些,这只是它的一个小项目。这可以通过其他方式实现吗?我愿意接受建议。

非常感谢 K

1 个答案:

答案 0 :(得分:1)

您尝试运行CGI脚本的方式是错误的。 CGI是Web服务器和服务器上的应用程序之间的协议。它总是需要某种Web服务器。您试图将HTTP请求发送到文件系统中包含Perl程序的文件。这表明了对网络工作原理的根本误解。

我的建议是为此而放弃CGI,并运行一个小型的独立Web应用程序,该应用程序带有自己的 Web服务器。它将打开一个端口,并允许您向其发送Web请求。它是便携式的,可扩展的并且易于维护。

如果您关心的只是使此工作轻松进行,那么Dancer2Mojolicious这两个Web框架都非常适合您的目的。该答案将重点放在Dancer2上,因为我对此比较熟悉。

首先从CPAN安装Dancer2。您似乎在Windows上,所以这可能是Strawberry Perl随附的cpanm客户端,或ActivePerl上的ppm

在文件系统中的某个位置创建一个名为 app.pl 的文件(名称并不重要)。粘贴以下代码。

use strict;
use warnings;
use Dancer2;
use Web::Scraper;

set serializer => 'JSON';

get '/:name' => sub {
    my ($self) = @_;

    return find_movie(route_parameters->get('name'));
};

# This is your data model/source. Could also put this in
# an extra package and make it have a nice interface. That way
# you can easily wrap caching around it, or switch to a database.
sub find_movie {
    my $name = shift;

#    my $scraper = Web::Scraper->new;
#    my $movie = $scraper->scrape();

    # this would be a data structure
#    return $movie;
    return { foo => $name };
}

Dancer2->psgi_app;

现在打开一个放置文件的终端(cmd),然后运行

$ plackup app.pl
HTTP::Server::PSGI: Accepting connections at http://0:5000/

您现在可以对此进行请求。以网址http://localhost:5000/red为例。

您也不必担心JSON的问题,set serializer位将负责为您发送回正确的内容类型,并将Perl数据结构自动转换为JSON。

使用Dancer2::Plugin::Cache::CHI之类的内容来缓存Web抓取搜索的结果现在也很简单。


如果您想了解有关PSGI的更多信息以及为什么CGI不是您正在做的事情的正确工具,请访问以下链接: