【问题标题】:How to determine where a request is coming from in a REST api如何在 REST api 中确定请求的来源
【发布时间】:2014-08-26 18:06:57
【问题描述】:

我有一个带有控制器的 RESTful API,当它被我的 android 应用程序点击时,它应该返回一个 JSON 响应,当它被网络浏览器点击时,它应该返回一个“视图”。我什至不确定我是否以正确的方式接近这一点。我正在使用 Laravel,这就是我的控制器的样子

class TablesController extends BaseController {

    public function index()
    {
        $tables  = Table::all();

        return Response::json($tables);
    }
}

我需要这样的东西

class TablesController extends BaseController {

    public function index()
    {
        $tables  = Table::all();

        if(beingCalledFromWebBrowser){
            return View::make('table.index')->with('tables', $tables);
        }else{ //Android 
            return Response::json($tables);
        }
    }

看看这些响应之间有何不同?

【问题讨论】:

    标签: php android rest laravel


    【解决方案1】:

    注意:这是给未来的观众的

    我发现使用前缀 api 进行 api 调用很方便。在路由文件中使用

    Route::group('prefix'=>'api',function(){
        //handle requests by assigning controller methods here for example
        Route::get('posts', 'Api\Post\PostController@index');
    }
    

    在上述方法中,我将 api 调用和 Web 用户的控制器分开。但是如果你想使用同一个控制器,那么Laravel Request 有一个方便的方法。您可以在控制器中识别前缀。

    public function index(Request $request)
    {
        if( $request->is('api/*')){
            //write your logic for api call
            $user = $this->getApiUser();
        }else{
            //write your logic for web call
            $user = $this->getWebUser();
        }
    }
    

    is 方法允许您验证传入请求 URI 是否与给定模式匹配。使用此方法时,您可以使用* 字符作为通配符。

    【讨论】:

    • 当您使用 cloudflare 之类的服务时,您的回答非常有用。因为我注意到当使用 ajax 发出 http 请求时,标头会被 cloudflare 更改,并且 Laravel 会根据 Accept 标头中的值确定请求是否需要 json。使用 $request->is('api/*') 而不是 $request->expectsJson() 对我来说就像一个魅力。
    【解决方案2】:

    使用这种方式。您可以简单地将 URL 识别为调用表单(Web 或 API)

    控制器代码

    if ( Request::capture()->expectsJson()  )
         {  return "API Method";  }
         else
         {  return "Web Method";     }
    

    路线代码

    对于 api.php Route::post("category","CategoryController@index");

    对于 Web.php Route::get("category","CategoryController@index");

    【讨论】:

      【解决方案3】:

      你可以使用

      if ($request->wantsJson()) {
           // enter code heree
      }
      

      【讨论】:

      • 恭喜您从 6 岁的已接受答案中复制了两行。
      【解决方案4】:

      你可以像这样使用Request::wantsJson()

      if (Request::wantsJson()) {
          // return JSON-formatted response
      } else {
          // return HTML response
      }
      

      基本上Request::wantsJson() 所做的是检查请求中的accept 标头是否为application/json 并基于此返回true 或false。这意味着您需要确保您的客户端也发送“accept: application/json”标头。

      请注意,我在这里的回答并不能确定“请求是否来自 REST API”,而是检测客户端是否请求 JSON 响应。我的回答应该仍然是这样做的方法,因为使用 REST API 并不一定意味着需要 JSON 响应。 REST API 可能会返回 XML、HTML 等。


      参考 Laravel 的Illuminate\Http\Request

      /**
       * Determine if the current request is asking for JSON in return.
       *
       * @return bool
       */
      public function wantsJson()
      {
          $acceptable = $this->getAcceptableContentTypes();
      
          return isset($acceptable[0]) && $acceptable[0] == 'application/json';
      }
      

      【讨论】:

      • 事情是,从浏览器访问 API 时,我的所有请求都没有使用 ajax。我应该吗?
      • 对,我已经修改了我的答案。您需要通过将请求中的 accept 标头设置为“application/json”来确保您的应用程序请求 json。稍后将更新其内部工作方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2018-11-12
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-06
      相关资源
      最近更新 更多