AngularJS 和 PHP 的不同服务器?

Posted

技术标签:

【中文标题】AngularJS 和 PHP 的不同服务器?【英文标题】:Different servers for AngularJS and PHP? 【发布时间】:2016-08-29 18:36:24 【问题描述】:

我开始开发一个具有 AngularJS 前端和 Laravel 后端的 Web 应用程序。在这个阶段,我的 XAMP htdocs 中有两个目录 - 一个是 AngularJS 项目,由本地端口 9000 上的 grunt 嵌入式服务器提供服务,另一个项目是 Laravel,由本地主机后 8081 上的 XAMP Apache/php 提供服务。我看到了问题$http 向其他 Laravel 应用程序和来自外部互联网的其他 url 请求,我用作测试 url - 显然这是由于跨站点安全保护

这让我想到了一个问题 - 前端/后端应用程序是否可以有两台服务器(或至少一台具有不同端口的服务器 - 每个端口可以由不同的服务器提供服务)?我知道这对于应该被 JSONP 请求替换的 GET 请求是可能的。但是其他 HTTP 动词呢?是否有 $http 方法可以向其他服务器或同一服务器/应用程序的其他端口发出 PUT、DELETE 和类似请求?

或者唯一的可能是在同一个应用程序的同一个服务器/端口上同时运行前端和后端。这意味着我应该将 AngularJS 作为 PHP 或 Java 应用程序的一部分托管,而不是为此使用 grunt,是这样吗?

最初的问题来自著名的 Angular JS http status -1 错误。我正在密切关注教程http://www.tutorials.kode-blog.com/laravel-5-angularjs-tutorial,我的代码是:

return $http(
    method: 'GET', //'JSONP',
    url: 'http://localhost:8081/testserver/server.php/api/v1/contracts',
    //url: 'http://jsonplaceholder.typicode.com/posts',
    timeout: 100000
  ).then(function(result) 
      alert(result);
      return result.data;
    ,
    function (error) 
      alert(error);
      console.log("v2 my object: %o", error);
      alert(JSON.stringify(error));
    
  );

当我向 localhost 发出请求时,出现 -1 错误,但我对 http://jsonplaceholder.typicode.com/posts 的请求给出了预期的答案。我尝试使用我的外部 IP 地址而不是 localhost,但错误仍然存​​在。我的服务器端代码显然使用了 Laravel Illuminate ->get() 函数,我认为该函数完成了将 Contract 对象数组转换为 JSON 响应所需的所有转换:

public function index($id = null) 
    if ($id == null) 
        //this branch is being tested 
        return Contract::orderBy('CONTRACT_NO', 'asc')->get();
     else 
        return $this->show($id);
    
 

服务器响应没有任何异常——它是 JSON 数组:

["CONTRACT_NO":"1","CUSTOMER":null,...]

【问题讨论】:

你需要查看 CORS 请求 我最初的问题是 AngularJS http status -1 著名的问题。我认为它与 CORS 连接,但我的 Angular 在 localhost:9000/#/contracts 上运行,它成功请求了 'url: 'jsonplaceholder.typicode.com/posts'' 但它为 localhost Laravel 服务抛出了 http 状态 -1。我不确定这是否是 CORS 您能否发布一些代码,显示您如何在客户端发出请求,以及您如何尝试在服务器端处理它 当您在浏览器中对localhost:8081/testserver/server.php/api/v1/contracts 执行 GET 操作时,您会得到预期的响应吗? 当然,我尝试将此网址放在我的 Chrome 地址栏中,并且有一个带有简单文本的白页 - JSON 响应。我猜它应该是 GET 请求,我不关心标题我猜默认值就足够了。 【参考方案1】:

可以通过在 Apache 服务器上配置虚拟主机来实现。可以通过使用不同的域名(或子域)、IP 地址或端口来进行区分。

端口 80 和 8080 上的示例配置:

Listen 80
Listen 8080

<VirtualHost 172.20.30.40:80>
    ServerName www.example.com
    DocumentRoot "/www/domain-80"
</VirtualHost>

<VirtualHost 172.20.30.40:8080>
    ServerName www.example.com
    DocumentRoot "/www/domain-8080"
</VirtualHost>

【讨论】:

【参考方案2】:

我使用以下Middleware 来处理 CORS 请求。如果没有类似的东西,您将无法支持向 Laravel 后端发出的 CORS 请求。

尝试使用类似以下的内容 - 当前设置为允许任何来源请求,在生产期间您可能希望将其收紧以仅允许来自已知来源的请求。

<?php

namespace App\Http\Middleware;

use Closure;
use Response;

class CorsMiddleware 

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
        // setup array of CORS headers
        $headers = [
            'Access-Control-Allow-Origin'   => '*',
            'Access-Control-Allow-Methods'  => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'  => 'Content-Type, Accept, Origin, Authorization, X-Requested-With',
            'Access-Control-Allow-Credentials'  => true,
            'Access-Control-Expose-Headers' => 'Authorization',
        ];

        // check for OPTIONS request
        if( $request -> getMethod() == 'OPTIONS')
        
            return Response::make('OK', 200, $headers);
        

        // add CORS headers to remaining requests
        $response = $next($request);
        foreach( $headers as $key => $value )
        
            $response -> headers -> set($key, $value);
        

        return $response;
    


您还可以查看此包以向 Laravel 添加 CORS 支持:https://github.com/barryvdh/laravel-cors

【讨论】:

就是这样!这是正确的解决方案。中间件应该在app/Http/Kernel.php中注册

以上是关于AngularJS 和 PHP 的不同服务器?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 PHP MySQL 更新数据库,其中数据来自 AngularJS1.2 服务

AngularJS绑定,多个控制器通过一个服务,部分页面由php渲染

angularJS怎么实现与服务端的PHP进行数据交互

如何使用来自不同模块的两个具有相同名称的 AngularJS 服务?

AngularJS:$http 服务 GET 到 php 服务器:请求方法:选项,状态代码:405 方法不允许

为啥 AngularJS 应用程序不能在不同的服务器上使用 REST 服务?