So bestimmen Sie, woher eine Anfrage in einer REST-API kommt
Lesezeit: 4 Minuten
franklot
Ich habe eine RESTful-API mit Controllern, die eine JSON-Antwort zurückgeben sollten, wenn sie von meiner Android-Anwendung getroffen wird, und eine “Ansicht”, wenn sie von einem Webbrowser getroffen wird. Ich bin mir nicht einmal sicher, ob ich das richtig angehe. Ich benutze Laravel und so sieht mein Controller aus
class TablesController extends BaseController {
public function index()
{
$tables = Table::all();
return Response::json($tables);
}
}
Ich brauche so etwas
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);
}
}
Sehen Sie, wie sich die Antworten voneinander unterscheiden?
Schafi
Hinweis::Dies ist für zukünftige Zuschauer
Den Ansatz fand ich mit einem Präfix bequem api für API-Aufrufe. Verwenden Sie in der Routendatei
Route::group('prefix'=>'api',function(){
//handle requests by assigning controller methods here for example
Route::get('posts', 'Api\Post\PostController@index');
}
Im obigen Ansatz trenne ich Controller für API-Anruf- und Webbenutzer. Aber wenn Sie dann den gleichen Controller verwenden möchten Laravel Request hat einen bequemen Weg. Sie können das Präfix in Ihrem Controller identifizieren.
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();
}
}
Die is -Methode können Sie überprüfen, ob der eingehende Anforderungs-URI einem bestimmten Muster entspricht. Sie können die verwenden * Zeichen als Platzhalter, wenn Sie diese Methode verwenden.
Ihre Antwort ist sehr nützlich, wenn Sie einen Dienst wie Cloudflare verwenden. Weil mir aufgefallen ist, dass bei einer HTTP-Anfrage mit Ajax die Header von Cloudflare geändert werden und Laravel anhand des Werts im Accept-Header bestimmt, ob eine Anfrage JSON erwartet. Die Verwendung von $request->is(‘api/*’) anstelle von $request->expectsJson() hat für mich wie ein Zauber funktioniert.
– Der Stompiest
7. November 2021 um 14:04 Uhr
Unnawut
Sie können verwenden Request::wantsJson() so was:
if (Request::wantsJson()) {
// return JSON-formatted response
} else {
// return HTML response
}
Im Grunde was Request::wantsJson() tut ist, dass es prüft, ob die accept Header in der Anfrage ist application/json und basierend darauf wahr oder falsch zurückgeben. Das bedeutet, dass Sie sicherstellen müssen, dass Ihr Client auch einen „accept: application/json“-Header sendet.
Beachten Sie, dass meine Antwort hier nicht bestimmt, ob „eine Anforderung von einer REST-API kommt“, sondern erkennt, ob der Client eine JSON-Antwort anfordert. Meine Antwort sollte jedoch immer noch der richtige Weg sein, da die Verwendung der REST-API nicht zwingend bedeutet, dass eine JSON-Antwort erforderlich ist. Die REST-API kann XML, HTML usw. zurückgeben.
/**
* 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';
}
Sache ist, dass ich Ajax nicht für alle meine Anfragen verwende, wenn ich vom Browser aus auf die API zugreife. sollte ich?
– franklot
5. Juli 2014 um 21:20 Uhr
Richtig, ich habe meine Antwort geändert. Sie müssen sicherstellen, dass Ihre App per Einstellung nach json fragt accept Header in der Anfrage an “application/json”. Werde in Kürze aktualisieren, wie es intern funktioniert.
– Unnawut
5. Juli 2014 um 21:26 Uhr
Verwenden Sie diesen Weg. Sie können die URL einfach als Aufrufformular identifizieren ( Web oder API )
Für api.php Route::post(“category”,”CategoryController@index”);
Für Web.php Route::get(“category”,”CategoryController@index”);
Sie können verwenden
if ($request->wantsJson()) {
// enter code heree
}
Verwendet Ihre App überhaupt andere Header oder Autorisierungstoken? Wenn dies der Fall ist, können Sie eine Hilfsfunktion erstellen, um die Header auf einen Schlüssel zu überprüfen. Unsere App sendet den Autorisierungs-Header (für Passport), während unser Web-Ende das Passport-Web-Cookie in der Websitzung verwendet, also schaue ich nur nach dem Autorisierungsschlüssel, um zu wissen, dass es sich um eine App handelt:
if(request()->hasHeader('Authorization')){
//is from app
}
Sprep
Nichts davon hat bei mir funktioniert, weil ich eine andere Streckenstruktur hatte.
Man könnte es auch so machen.
public function __construct(Request $request) {
$this->request = $request;
$this->isApi = $this->request->segment(1) === 'api' ? true : false;
}
Verwenden Sie es dann so in Ihrem Controller.
if($this->isApi){
//do things for api view
} else {
//do things for html view
}
Ich hoffe es hilft.
Imran
You can easily check the route that came from either web or API with this.
if($request->route()->getPrefix() === 'api') {
// Your logic
}
14404400cookie-checkSo bestimmen Sie, woher eine Anfrage in einer REST-API kommtyes