Điểm:0

Làm cách nào để đăng PDF?

lá cờ km

Tôi đã làm theo các bước sau để đăng tệp PDF lên Drupal.

  1. Bật API JSON để tạo tại admin/config/services/jsonapi

  2. Kích hoạt tài nguyên POST phương tiện

    Phương tiện /phương tiện/{phương tiện}/chỉnh sửa: NHẬN, VÁ, XÓA
          / thực thể/phương tiện: POST
    
    Phương thức: POST, định dạng: json: xác thực: cookie
    
  3. Tạo một ứng dụng Angular và nhúng nó vào trang Drupal dưới dạng một khối

Ứng dụng Angular chụp trang bằng jspdf và nhúng hình ảnh vào PDF. Thay vì sử dụng thiết bị chặn, tôi nhận được mã thông báo với mỗi yêu cầu.

this.certificateService.getCsrf().subscribe(token => {
  this.certificateService.uploadMedia(pdf.output('blob'), fileName, token).subscribe({
    hoàn thành: () => {
      console.log('phương tiện đã đăng');
    }
  })
});

getCsrf() lấy mã thông báo dưới dạng văn bản.

getCsrf(): Có thể quan sát được<chuỗi> {
  const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');

  trả về this.httpClient.get(this.host + '/session/token',{ headers: headers, responseType: 'text'}).pipe(catchError(this.handleError<any>('token')))
}

tải lênMedia() cố gắng đăng tệp PDF lên phương tiện tới Drupal.

uploadMedia(pdf: Blob, tên: chuỗi, mã thông báo: chuỗi): Có thể quan sát được<bất kỳ> {
  const formData: FormData = new FormData();
  formData.append('chứng chỉ', pdf, tên);
  tiêu đề const = HttpHeaders mới();
  headers.set('Chấp nhận', 'application/vnd.api+json');
  headers.set('X-CSRF-Token',token);
  // headers.set('Kiểu nội dung','application/octet-stream');
  headers.set('Kiểu nội dung','application/hal+json');
  headers.set('Bố trí nội dung',`file; filename=${name}`);

  trả về this.httpClient.post(this.host + '/entity/media', formData, {headers: headers})
    .đường ống(
      catchError(this.handleError<any>('uploadMedia'))
    );
}

lỗi tôi nhận được là 415 Loại phương tiện không được hỗ trợ.

415 Loại phương tiện không được hỗ trợ

Tôi đang sử dụng Angular 13 và Drupal 9.

Tôi đã xem nhật ký lỗi Drupal; nó báo cáo ngoại lệ sau đây.

Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: Không tìm thấy tuyến nào phù hợp với "Loại nội dung: multipart/form-data; ranh giới=----WebKitFormBoundaryYAzO5lNTfgLQwQ9" trong Drupal\Core\Routing\ContentTypeHeaderMatcher->filter()

Việc chỉ đặt tiêu đề Loại nội dung không phải lúc nào cũng thay đổi tiêu đề loại nội dung được đăng. ví dụ. Với cả axios và góc http nếu bạn đăng một Biểu mẫuDữ liệu mảng, bạn sẽ nhận được một biểu mẫu nhiều phần mặc dù tiêu đề của bạn ở cấp độ cuộc gọi là ứng dụng/octet-stream

Sử dụng axios trong góc như sau dẫn đến 'application/octet-stream':

nhập Axios từ 'axios-observable'; 
Axios.defaults.headers.post['X-CSRF-Token'] = mã thông báo;
trả về Axios.post(this.host + '/entity/media', pdf, {
  tiêu đề: {
    Chấp nhận: `application/json, text/plain, */*',
    Ủy quyền: `Cơ bản ${basic}`,
    Bánh quy: ${cookie}; XDEBUG_SESSION=13681',
    'Loại nội dung': 'ứng dụng/octet-stream',
  }
});

Truyền dữ liệu PDF thô dẫn đến 'application/pdf'

tiêu đề const = HttpHeaders mới();
headers.set('Kiểu nội dung', 'ứng dụng/octet-stream');
trả lại this.httpClient.post(this.host + '/entity/media', pdf, {headers: headers})
  .đường ống(
    catchError(this.handleError<any>('uploadMedia'))
);

Xem lại trang dịch vụ còn lại quản trị/cấu hình/dịch vụ/phần còn lại, định dạng nội dung được phép là 'json'

Gỡ lỗi xác nhận rằng symfony đang kiểm tra giá trị này

Symfony chấp nhận JSON

Đang thử giao diện REST, tức là '/jsonapi/media/document/field_media_document/'

Có, có yêu cầu loại nội dung 'bin' trong web/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php mà

// Thêm kiểm tra truy cập định dạng kiểu nội dung. Điều này sẽ thực thi rằng tất cả
// các yêu cầu đến chỉ có thể sử dụng 'application/octet-stream'
// Tiêu đề kiểu nội dung.

Các /thực thể/phương tiện Url yêu cầu API JSON không cần một yêu cầu JSON theo web/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php

yêu cầu phương tiện truyền thông json

Điểm:0
lá cờ cn

Tôi sử dụng Angular, không phải React, nhưng tôi khá chắc chắn rằng phần này sai:

  // headers.set('Kiểu nội dung','application/octet-stream');
  headers.set('Kiểu nội dung','application/hal+json');

Các tập tin cần phải được đăng dưới dạng ứng dụng/octet-stream. Nó không phải là một đối tượng JSON; đó là một tập tin.

Ngoài ra, bạn có thể cần phải xoa bóp dữ liệu PDF thành thứ gì đó mà JSON:API hiểu được. Ví dụ, đây là tài liệu về cách thực hiện việc này với axios/Node.js.

Trong trường hợp của tôi, đối với các tệp hình ảnh, tôi phải đọc tệp dưới dạng đốm màu (Mã phản ứng, nhưng có thể cung cấp một ví dụ):

// https://stackoverflow.com/a/46568146
hàm readFileBlob(fileBlob: Blob) {
  trả lại Lời hứa mới ((giải quyết) => {
    đầu đọc const = FileReader mới();
    reader.onload = () => {
      giải quyết (reader.result);
    };
    reader.onabort = () => Promise.reject(Lỗi('việc đọc tệp bị hủy bỏ'));
    reader.onerror = () => Promise.reject(Lỗi('đọc tệp không thành công'));
    reader.readAsArrayBuffer(fileBlob);
  });
}

// fileToPost là một chuỗi chứa blob:
// blob:http://localhost:8100/00507d3e-7f6f-4f48-be80-b55c8bc20dd3
const postAuthFileBlob = async (
  tìm nạpUrl: chuỗi,
  fileToPost: chuỗi,
  // Tìm nạp có thể trả về bất kỳ thứ gì.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): Lời hứa<bất kỳ> => {
  const fileBlob = đang chờ tìm nạp(fileToPost).then((res) => res.blob());
  const arrayStr = (chờ readFileBlob(fileBlob)) làm ArrayBuffer;
  trả về postAuthFileBlobPart2(fetchUrl, arrayStr);
};
Interlated avatar
lá cờ km
Tôi nghĩ rằng bạn đang ở gần. Back-end đang phàn nàn rằng loại nội dung là nhiều phần/biểu mẫu dữ liệu thay vì ứng dụng/octet-stream
Interlated avatar
lá cờ km
Chỉ cần đăng bản pdf sẽ cho ứng dụng/pdf trả về this.httpClient.post(this.host + '/entity/media', pdf, {headers: headers}). Vẫn không thể tìm thấy drupal phù hợp cho ứng dụng/pdf. Không tìm thấy tuyến nào phù hợp với "Loại nội dung: ứng dụng/pdf" trong Drupal\Core\Routing\ContentTypeHeaderMatcher->filter() (dòng 49 của
lá cờ cn
@Interlated Như tôi đã nói, bạn cần đăng dưới dạng `application/octet-stream`. Vì một số lý do, bạn đã nhận xét điều đó trong mã của mình, nhưng bạn phải đăng dưới dạng `application/octet-stream` nếu bạn muốn tải lên bất kỳ tệp nhị phân nào.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.