Как удалить ошибку 500 для загрузки изображения с помощью Angular и PHP

#php #mysql #angular #typescript #codeigniter

#php #mysql #angular #typescript #codeigniter

Вопрос:

Как я могу устранить ошибку POST 500? При загрузке изображения я получаю:

scheduleTask @ zone-evergreen.js: 2845 scheduleTask @ zone-evergreen.js:385 onScheduleTask @ zone-evergreen.js:272 scheduleTask @ zone-evergreen.js:378 scheduleTask @ zone-evergreen.js: 210 scheduleMacroTask @ zone-evergreen.js:233 schedulemacrotask с текущей зоной @ zone-evergreen.js: 1134 (анонимный) @ zone-evergreen.js: 2878 proto. @ zone-evergreen.js:1449 отправить @ AjaxObservable.js:156 AjaxSubscriber @ AjaxObservable.js:122 _подписка @ AjaxObservable.js:93 _trySubscribe @ Observable.js:42 подписаться @ Observable.js:28 На выбранный файл @ uploader.component.ts:39 Загрузчик компонентов_template_input_change_30_listener @ uploader.component.html :32 executeListenerWithErrorHandling @ core.js:14310 wraplistenerin_markdirty и preventDefault @ core.js:14345 (анонимный) @ platform-browser.js:582 invokeTask @ zone-evergreen.js:399 onInvokeTask @ core.js:27418 invokeTask @ zone-evergreen.js:398 RunTask @ zone-evergreen.js:167invokeTask @ zone-evergreen.js: 480 invokeTask @ zone-evergreen.js: 1621 globalZoneAwareCallback @ zone-evergreen.js:1647

uploader.service.ts

 import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ajax } from 'rxjs/ajax';

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

  apiUrl = 'https://xxxx.com/api/index.php/';

  constructor(private http: HttpClient) { }

  uploadImage(formData) {
    return ajax.post(`${this.apiUrl}api/upload`, formData);
  }

  deleteImage(formData) {
    return this.http.post<any>(`${this.apiUrl}api/deleteImage`, formData)
      .pipe(
        catchError(this.handleError)
      );
  }

  saveUser(formData) {
    return this.http.post<any>(`${this.apiUrl}api/saveUser`, formData)
      .pipe(
        catchError(this.handleError)
      );
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(`Backend returned code ${error.status}, `   `body was: ${error.error}`);
    }
    // Return an observable with a user-facing error message.
    return throwError('Something bad happened. Please try again later.');
  }
}
  

uploader.component.ts

     import { Component, OnInit, Renderer2, ElementRef, ViewChild, EventEmitter, Output } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { UploaderService } from '../uploader.service';

@Component({
  selector: 'app-uploader',
  templateUrl: './uploader.component.html',
  styleUrls: ['./uploader.component.css']
})
export class UploaderComponent implements OnInit {

  userForm: FormGroup;
  error: string;
  uploadError: string;

  @ViewChild('image') private image: ElementRef;
  @Output() close = new EventEmitter();

  constructor(
    private fb: FormBuilder,
    private uploaderService: UploaderService,
    private renderer: Renderer2
  ) { }

  ngOnInit() {
    this.userForm = this.fb.group({
      user_name: [''],
      curp: [''],
      email: ['']
    });
  }

  onSelectedFile(event) {
    if (event.target.files.length > 0) {
      const productImage = event.target.files[0];

      const formData = new FormData();
      formData.append('productImage', productImage);
      this.uploaderService.uploadImage(formData).subscribe(
        res => {
          if (res.status === 200 amp;amp; res.response.status === 'success') {
            this.uploadError = '';

            const li: HTMLLIElement = this.renderer.createElement('li');

            const img: HTMLImageElement = this.renderer.createElement('img');
            img.src = res.response.imagePath;
            this.renderer.addClass(img, 'product-image');

            const a: HTMLAnchorElement = this.renderer.createElement('a');
            a.innerText = 'Delete';
            this.renderer.addClass(a, 'delete-btn');
            a.addEventListener('click', this.deleteUserImage.bind(this, res.response.filename, a));

            this.renderer.appendChild(this.image.nativeElement, li);
            this.renderer.appendChild(li, img);
            this.renderer.appendChild(li, a);
          } else {
            this.uploadError = res.response.message;
          }
        },
        err => this.error = err
      );
    }
  }

  deleteUserImage(filename, a) {
    const formData = new FormData();
    formData.append('filename', filename);
    this.uploaderService.deleteImage(formData).subscribe(
      res => {
        a.parentElement.remove();
      },
      err => this.error = err
    );
  }

  onSubmit() {
    const formData = new FormData();
    formData.append('user_name', this.userForm.get('user_name').value);
    formData.append('curp', this.userForm.get('curp').value);
    formData.append('email', this.userForm.get('email').value);
    this.uploaderService.saveUser(formData).subscribe(
      res => {
        if (res.status === 'success') {
          this.onClose(res);
        }
      },
      err => this.error = err
    );
  }

  onClose(data: any) {
    this.close.emit(data);
  }
}
  

Контроллер Api.php

 <?php
defined('BASEPATH') or exit('No direct script access allowed');

class Api extends CI_Controller
{

    public function __construct()
    {
        parent::__construct();
        $this->load->model('api_model');
    }

    public function upload()
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Request-Headers: GET,POST,OPTIONS,DELETE,PUT");

        $filename = NULL;

        $isUploadError = FALSE;
        $fullPath = '';

        if ($_FILES amp;amp; $_FILES['productImage']['name']) {

            $config['upload_path']          = './tmp';
            $config['allowed_types']        = 'jpg|jpeg|png|gif';
            $config['max_size']             = 10024;

            $this->load->library('upload', $config);
            if (!$this->upload->do_upload('productImage')) {

                $isUploadError = TRUE;

                $response = array(
                    'status' => 'error',
                    'message' => $this->upload->display_errors()
                );
            } else {
                $uploadData = $this->upload->data();
                $filename = $uploadData['file_name'];
                $fullPath = base_url('tmp/' . $filename);
            }
        }

        if (!$isUploadError) {

            $response = array(
                'status' => 'success',
                'filename' => $filename,
                'imagePath' => $fullPath
            );
        }

        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($response));
    }

    public function deleteImage()
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Request-Headers: GET,POST,OPTIONS,DELETE,PUT");

        $filename = $this->input->post('filename');
        $filePath = './tmp/' . $filename;

        if (file_exists($filePath)) {
            if (unlink($filePath)) {
                $response = array(
                    'status' => 'deleted'
                );
            } else {
                $response = array(
                    'status' => 'not delete'
                );
            }
        } else {
            $response = array(
                'status' => 'file not exist'
            );
        }

        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($response));
    }

    public function saveUser()
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Request-Headers: GET,POST,OPTIONS,DELETE,PUT");

        $user_name = $this->input->post('user_name');
        $curp = $this->input->post('curp');
        $email = $this->input->post('email');

        if ($user_name) {

            $userData = array(
                'user_name' => $user_name,
                'curp' => $curp,
                'email' => $email,
                'is_active' => 1,
                'created_at' => date('Y-m-d H:i:s', time())
            );

            $id = $this->api_model->insert_user($userData);

            $tmpDir    = 'tmp';
            $files = scandir($tmpDir);

            $imageData = array();
            foreach ($files as $filename) {

                if (!in_array($filename, array(".", ".."))) {

                    $imageData[] = array(
                        'user_id' => $id,
                        'image' => $filename
                    );

                    rename('tmp/' . $filename, 'uploads/' . $filename);
                }
            }
            if (!empty($imageData)) {
                $this->api_model->insert_user_image($imageData);

                $response = array(
                    'status' => 'success',
                    'message' => 'User added successfully'
                );
            } else {
                $response = array(
                    'status' => 'error'
                );
            }
        }

        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($response));
    }
}
?>
  

Модель Api_model.php

 <?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Api_model extends CI_model {
    
    public function insert_user($userData)
    {
        $this->db->insert('users',$userData);
        return $this->db->insert_id();
    }

    public function insert_user_image($imageData)
    {
        $this->db->insert_batch('user_images', $imageData);
    }
}
?>
  

Ответ №1:

в этой части:

  return ajax.post(`${this.apiUrl}api/upload`, formData);
  

замените на это:

 const headers = new HttpHeaders().set('Accept', 'application/json');
return this.http.post(`${this.apiUrl}api/upload`, formData, { headers }).pipe(map((resp: any) => { return resp; }));
  

Это я использую для загрузки файлов и данных в службу.