温馨提示:本文翻译自stackoverflow.com,查看原文请点击:Ionic - API with laravel json response
api http ionic-framework json laravel

Ionic - 具有laravel json响应的API

发布于 2020-04-11 14:10:36

我尝试在laravel项目中使用API​​创建示例离子应用程序。我做了Laravel json响应api路由。但是在我的Ionic主页中没有任何显示,并且向我报告了此错误:Access to XMLHttpRequest at 'http://b.1p1eqpotato.com/ib/?p=1' from origin 'http://localhost:8100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. zone-evergreen.js:2952 POST http://b.1p1eqpotato.com/ib/?p=1 net::ERR_FAILED这是console.log我的laravel帖子(3) [{…}, {…}, {…}]0: {id: 1, name: "John Doe", course: "Udemy Academy", created_at: "2020-02-01 13:14:40", updated_at: "2020-02-01 13:14:40"}1: {id: 2, name: "Mike Doe", course: "Software Engineering", created_at: "2020-02-01 13:16:43", updated_at: "2020-02-01 13:16:43"}2: {id: 3, name: "Trevor Doe", course: "Api Ionic Laravel", created_at: "2020-02-01 13:58:24", updated_at: "2020-02-01 13:58:24"}length: 3__proto__: Array(0) udnefined home.page.ts:24

这是我的离子代码。

我的app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule, HttpClient } from '@angular/common/http';

@NgModule({
    declarations: [ AppComponent ],
    entryComponents: [],
    imports: [ BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule ],
    providers: [ StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ],
    bootstrap: [ AppComponent ]
})
export class AppModule {}

我的api.service.ts

import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { catchError, tap, map } from 'rxjs/operators';

const httpOptions = {
  headers: new HttpHeaders({'Content-type': 'applications/json'})
}

const apiUrl = "http://localhost:8000/api/students";

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) { }

  private handleError(error: HttpErrorResponse) {
    if(error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(
        `Backend returned code ${error.status},` +
        `body was: ${error.error}`
      );
    }
    return throwError('Something is wrong, please try again.');
  }

  private extractData(res: Response) {
    let body = res;
    return body || { };
  }

  getDataUser(): Observable<any> {
    return this.http.get(apiUrl, httpOptions).pipe(
      map(this.extractData),
      catchError(this.handleError)
    );
  }
}

这是home.page.ts

import { Component } from '@angular/core';
import { ApiService } from './../api.service';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  datauser: any;
  constructor(
    public api: ApiService
  ) {}

  ngOnInit(){
    this.getDataUser();
  }

  async getDataUser() {
    await this.api.getDataUser()
      .subscribe(res => {
        console.log(res);
        this.datauser = res.results;
    console.log(this.datauser);
      }, err => {
        console.log(err);
      });
  }
}

这是我的home.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item *ngFor="let data of datauser">
      {{data.name}}
    </ion-item>
  </ion-list>
</ion-content>

因此它array在控制台中显示了我,但是在“主页”视图上没有任何显示。并出现此错误:有没有解决方案,因此视图上不会显示此XMLHttpRequest错误?请帮忙!谢谢

已编辑

这是我的 ApiController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Student;

class ApiController extends Controller
{
    public function getAllStudents() {
        // logic to get all students goes here
        $students = Student::get()->toJson(JSON_PRETTY_PRINT);
        return response($students, 200);
      }

      public function createStudent(Request $request) {
        // logic to create a student record goes here
        $student = new Student;
        $student->name = $request->name;
        $student->course = $request->course;
        $student->save();

        return response()->json([
            "message" => "student record created"
        ], 201);
      }

      public function getStudent($id) {
        // logic to get a student record goes here
      }

      public function updateStudent(Request $request, $id) {
        // logic to update a student record goes here
      }

      public function deleteStudent ($id) {
        // logic to delete a student record goes here
      }
  }

这是我的api.php路线:

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::get('students', 'ApiController@getAllStudents');
Route::get('students/{id}', 'ApiController@getStudent');
//Route::post('students', 'ApiController@createStudent');
Route::put('students/{id}', 'ApiController@updateStudent');
Route::delete('students/{id}','ApiController@deleteStudent');

这是我的Student.php模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    protected $table = 'students';

    protected $fillable = ['name', 'course'];
}

查看更多

提问者
Milos
被浏览
128
Foued MOUSSI 2020-02-02 10:31

根据Mozilla开发者网站的说法,当Web应用程序尝试向源(域,协议和端口)与源不同的资源发送请求时,就会发生CORS。在我的情况下,http请求是从与目标资源(本地主机)相同的主机发出的,但端口号不同。

如果您用谷歌搜索“如何修复/允许CORS”,那么您会发现一些网站告诉您通过修改Web服务器配置将额外的标头添加到HTTP响应中。但是,如果您对服务器配置的了解很少,或者无法联系到基础架构师以寻求帮助,请使用另一种方法。

什么是中间件?

中间件是一种过滤进入您的应用程序的HTTP请求的机制,因此您可以以非常方便的方式轻松地修改HTTP请求和响应。

现在,让我们逐步进行:

创建类CorsMiddleware.php在目录内创建一个新文件app\Http\Middleware

<?php

/**
* Location: /app/Http/Middleware
*/
namespace App\Http\Middleware;

use Closure;

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

        if ($request->isMethod('OPTIONS'))
        {
            return response()->json('{"method":"OPTIONS"}', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value)
        {
            $response->header($key, $value);
        }

        return $response;
    }
}

此类用于修改Http Response标头,这里重要的是第22行,我们告诉浏览器接受来自任何来源的请求(*)

'Access-Control-Allow-Origin' => '*'

注册中间件

接下来要让CorsMiddlewareLaravel知道该类,您必须在中注册app\Http\Kernel.php

$app->middleware([
    //...
    App\Http\Middleware\CorsMiddleware::class
]);

现在,您将不再发现该错误。

阅读全文