繁体   English   中英

Angular 8 + Laravel 6 表单数据

[英]Angular 8 + Laravel 6 FormData

我有一个使用 angular 8 和 api laravel 6 的前端应用程序。此应用程序需要身份验证才能访问仪表板。 在其中一个模块中,除了其他字段外,我还需要上传一张图片。 但是,即使我使用 Angular 的 FormData,我的 api 总是返回空。 如果我发送一个普通的 JSON,我只返回我发送的字段,但我也需要发送一个图像

我的html:

<div class="row">
<div class="col-md-12">
        <h4 class="remove-margin">Adicionar novo professor </h4>
        <div class="card">
          <div class="card-header">
            <!-- <h5 class="card-title">Edit Profile</h5> -->
          </div>
          <div class="card-body">
            <form [formGroup]="registerForm" (ngSubmit)="registerProfessores()">
            <div class="row">
                <div class="col-md-12">
                    <div class="form-group">
                        <label>Foto</label>
                        <input class="form-control" name="foto" type="file" (change)="uploadFile($event)" >
                        <div *ngIf="fileUploadProgress">
                            Upload progress: {{ fileUploadProgress }}
                        </div>
                        <div class="image-preview mb-3" *ngIf="preview && preview !== null">
                            <img [src]="preview" height="300" />                 
                        </div>

                        <label for="file-upload" id="file-drag">
                            <img id="file-image" src="#" alt="Preview" class="hidden">
                            <div id="start" >
                                <i class="fa fa-download" aria-hidden="true"></i>
                                <div>Select a file or drag here</div>
                                <div id="notimage" class="hidden">Please select an image</div>
                                <span id="file-upload-btn" class="btn btn-primary">Select a file</span>
                                <br>
                                <span class="text-danger"></span>
                            </div>

                        </label>
                    </div>
                </div>
            </div>
              <div class="row">
                  <div class="col-md-12">
                      <div class="form-group">
                      <label>Nome</label>
                      <input type="text" name="nome" formControlName="nome" class="form-control" placeholder="Nome">

                      <small id="emailHelp" class="form-text text-muted" *ngIf="serverErrors">{{ serverErrors.name }}</small>

                      </div>
                  </div>
              </div>

              <div class="row">
                <div class="col-md-12">
                    <div class="form-group">
                        <label>Currículo resumido</label>
                        <textarea name="curriculo" formControlName="curriculo" name="curriculo" class="form-control" placeholder="Currículo"></textarea>
                    </div>
                </div>
              </div>

              <div class="row">
                <div class="col-md-12">
                    <div class="form-group">
                        <label>Currículo Lates</label>
                        <input type="text" name="link" formControlName="link" name="link" class="form-control" placeholder="Currículo Lates" >
                    </div>
                </div>
              </div>

                <div class="row">
                  <div class="update ml-auto mr-auto">
                    <button type="submit" class="btn btn-primary btn-round" [disabled]="!registerForm.valid">Salvar</button>
                  </div>
                </div>
              </form>
          </div>
        </div>
      </div>

我的组件.ts

    ngOnInit() {
    this.registerForm = this.fb.group({
      nome: [''],
      curriculo: [''],
      link: [''],
      foto: [null]
    })
  }

  uploadFile(event){
    const file = (event.target as HTMLInputElement).files[0];
    this.registerForm.patchValue({
      foto: file
    })
    this.registerForm.get('foto').updateValueAndValidity();

    const reader = new FileReader();
    reader.onload = () => {
      this.preview = reader.result as string
    }
    reader.readAsDataURL(file);
  }

  registerProfessores(){ 
    this.professorRest.storeProfessor(this.registerForm).subscribe(
      response => {
        console.log('RESPONSE-----------',response),
        this.router.navigate(['professores'])
      },
      error =>{
        this.serverErrors = error.error.errors
      } 
    );
  } 

我的服务.ts

import { Injectable, ɵConsole } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/internal/Observable';

const HttpUploadOptions = {
  headers: new HttpHeaders({ "Content-Type": "multipart/form-data" })
}

@Injectable({
  providedIn: 'root'
})
export class ProfessorRestService {
  professores: Array<{id: number, nome: string, foto: string, curriculo: string}> = [];
  constructor(private http: HttpClient) { }

  getProfessores(): Observable<any> {
    return this.http.get('http://localhost/server/public/api/professor-list');
  }

  editProfessor(id): Observable<any> {
    return this.http.get('http://localhost/server/public/api/professor-list/' + id);
  }

  updateProfessor(form,id): Observable<any> {
    return this.http.put('http://localhost/server/public/api/professor-list/' + id, form.value);
  }

  storeProfessor(form): Observable<any> {

/*     const input = {
      nome: form.get('nome').value,
      curriculo: form.get('curriculo').value,
      link: form.get('link').value,
      foto: form.get('foto').value
    } */


    const input = new FormData();
    input.append('nome', form.value.nome)
    input.append('curriculo', form.value.curriculo)
    input.append('link', form.value.link)
    input.append('foto', form.value.foto)

    return this.http.post('http://localhost/server/public/api/professor-list',input,HttpUploadOptions);
  }

  deleteProfessor(id): Observable<any> {
    return this.http.delete('http://localhost/server/public/api/professor-list/' + id);
  }
}

我的拦截器

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {    
    // note add this header for CORS pass
    let token = localStorage.getItem('token');
    let headers = null;

    if(token){
      headers = new HttpHeaders({
        'Content-Type' : 'application/form-data; charset=UTF-8, application/json',
        'Authorization' : `Bearer ${token}`,
      });
    }else{
      headers = new HttpHeaders({
        'Content-Type' : 'application/form-data; charset=UTF-8, application/json'
    });
    }
    const requestChange = req.clone({headers});
    console.log(requestChange);
    return next.handle(requestChange);
  }
} 

这是我在 laravel 中的控制器

    <?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Professor;

class ProfessorListController extends Controller
{
    public function __construct()
    {
        //$this->middleware('auth:api');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
        $professor = Professor::get();
        return response()->json(['professor' => $professor], 200);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

        return response()->json(['TODOS' => $request->all()]);


        if($files = $request->file('foto')){
            $destinationPath = 'public/image/';
            $profileImage = date('YmdHis') .  "." . $files->getClientOriginalExtension();
            $files->move($destinationPath, $profileImage);
        }

        $professor = Professor::create([
            'nome' => $request->nome,
            'foto' => $profileImage,
            'curriculo' => $request->curriculo,
            'link' => $request->link
        ]);

        return response()->json(['professor' => "Professor criado com sucesso"], 200);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
        $professor = Professor::find($id);
        return response()->json(['professor' => $professor], 200);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
        $professor = Professor::find($id);
        return response()->json(['professor' => $professor], 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $professor = Professor::find($id);

        $professor->update($request->all());
        return response()->json(['professor' => $professor,'message' => 'Professor Updated Successfully'], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $professor = Professor::find($id);
        $professor->delete();
        return response()->json(['professor' => $professor,'message' => 'Professor Deleted Successfully'], 200);
    }
}

后端响应

前端

问题解决了。 只需从拦截器中删除“内容类型”

my interceptor

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {    
    // note add this header for CORS pass
    let token = localStorage.getItem('token');
    let headers = null;

    if(token){
      headers = new HttpHeaders({

        'Authorization' : `Bearer ${token}`,
      });
    }else{
      headers = new HttpHeaders({

    });
    }
    const requestChange = req.clone({headers});
    console.log(requestChange);
    return next.handle(requestChange);
  }
} 

我试图将 angular 13 的图像上传到 laravel 8。这解决了我无法执行 dd($request->file('image')) 的问题。 这一直返回 ^null。 不知道为什么会这样。 我已将 multipart/form-data 添加到我的角度表单中,但这并没有帮助。 仅按照 OP 的建议从 httpOptions 中删除标头即可修复它。 尽管我遇到了这篇文章,但我想知道这里发生了什么: https ://github.com/angular/angular/issues/37597。 长得有点像

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM