首页 > 解决方案 > 如何在本地将 JSON 数据从 perl 脚本传递到角度控制器

问题描述

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 网络抓取库。抓取工作正常,为简洁起见,我不会包含整个 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

标签: angularperlhttp

解决方案


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

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

如果您关心的只是让它轻松工作,那么任何一个 Web 框架Dancer2Mojolicious都非常适合您的目的。这个答案将集中在 Dancer2 上,因为我更熟悉它。

首先从 CPAN 安装 Dancer2。您似乎在 Windows 上,所以这可能是Strawberry Perl 或ActivePerlcpanm附带的客户端。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/

您现在可以对此提出请求。以 URLhttp://localhost:5000/red为例。

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

现在使用Dancer2::Plugin::Cache::CHI之类的东西来缓存来自网络抓取搜索的结果也很简单。


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


推荐阅读