Tôi đã làm theo các bước sau để đăng tệp PDF lên Drupal.
Bật API JSON để tạo tại admin/config/services/jsonapi
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
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ợ.
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
Đ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