Score:0

ฉันจะโพสต์ PDF ได้อย่างไร

ธง km

ฉันทำตามขั้นตอนเหล่านี้เพื่อโพสต์ไฟล์ PDF ไปยัง Drupal

  1. เปิดใช้ JSON API เพื่อสร้างที่ admin/config/services/jsonapi

  2. เปิดใช้งานทรัพยากรสื่อ POST

    สื่อ /media/{media}/edit: GET, PATCH, DELETE
          /เอนทิตี/สื่อ: POST
    
    วิธีการ: POST, รูปแบบ: json: การรับรองความถูกต้อง: คุกกี้
    
  3. สร้างแอปพลิเคชันเชิงมุมและฝังลงในหน้า Drupal เป็นบล็อก

แอปพลิเคชันเชิงมุมจับภาพหน้าโดยใช้ jspdf และฝังรูปภาพใน PDF แทนที่จะใช้ตัวสกัดกั้น ฉันได้รับโทเค็นในแต่ละคำขอ

this.certificateService.getCsrf().subscribe(โทเค็น => {
  this.certificateService.uploadMedia(pdf.output('blob'), fileName, token).subscribe({
    สมบูรณ์: () => {
      console.log('สื่อที่โพสต์');
    }
  })
});

getCsrf() คว้าโทเค็นเป็นข้อความ

getCsrf (): สังเกตได้ <string> {
  ส่วนหัวของ const = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');

  ส่งคืน this.httpClient.get(this.host + '/session/token',{ headers: headers, responseType: 'text'}).pipe(catchError(this.handleError<any>('token')))
}

อัปโหลดสื่อ () พยายามโพสต์ไฟล์ PDF ไปยังสื่อไปยัง Drupal

uploadMedia(pdf: Blob, ชื่อ: string, token: string): Observable<any> {
  Const formData: FormData = ใหม่ FormData();
  formData.append('ใบรับรอง', pdf, ชื่อ);
  ส่วนหัว const = HttpHeaders ใหม่ ();
  headers.set('ยอมรับ', 'application/vnd.api+json');
  headers.set('X-CSRF-โทเค็น',โทเค็น);
  // headers.set('Content-Type','application/octet-stream');
  headers.set('ประเภทเนื้อหา','application/hal+json');
  headers.set('การจัดการเนื้อหา',`file; filename=${name}`);

  ส่งคืน this.httpClient.post (this.host + '/entity/media', formData, {ส่วนหัว: ส่วนหัว})
    .ท่อ(
      catchError(this.handleError<ใดๆ>('uploadMedia'))
    );
}

ข้อผิดพลาดที่ฉันได้รับคือ 415 ประเภทสื่อที่ไม่รองรับ.

415 ประเภทสื่อที่ไม่รองรับ

ฉันใช้ Angular 13 และ Drupal 9

ฉันดูบันทึกข้อผิดพลาดของ Drupal; มันรายงานข้อยกเว้นต่อไปนี้

Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: ไม่พบเส้นทางที่ตรงกับ "Content-Type: multipart/form-data; border=----WebKitFormBoundaryYAzO5lNTfgLQwQq9" ใน Drupal\Core\Routing\ContentTypeHeaderMatcher->filter()

การตั้งค่าส่วนหัวของประเภทเนื้อหาไม่ได้เปลี่ยนส่วนหัวของประเภทเนื้อหาที่โพสต์เสมอไป เช่น. ด้วย axios และ http เชิงมุมหากคุณโพสต์ไฟล์ ข้อมูลแบบฟอร์ม อาร์เรย์ คุณจะได้รับแบบฟอร์มหลายส่วน แม้ว่าส่วนหัวของคุณในระดับการโทรจะเป็น application/octet-stream

การใช้ axios ภายในเชิงมุมจะส่งผลให้ 'application/octet-stream':

นำเข้า Axios จาก 'axios-observable'; 
Axios.defaults.headers.post['X-CSRF-Token'] = โทเค็น;
ส่งคืน Axios.post (this.host + '/entity/media', pdf, {
  ส่วนหัว: {
    ยอมรับ: `application/json, text/plain, */*',
    การอนุญาต: `Basic ${basic}`,
    คุกกี้: ${คุกกี้}; XDEBUG_SESSION=13681',
    'ประเภทเนื้อหา': 'แอปพลิเคชัน/ออคเต็ตสตรีม'
  }
});

การส่งผ่านข้อมูล PDF ดิบจะส่งผลให้เป็น 'application/pdf'

ส่วนหัว const = HttpHeaders ใหม่ ();
headers.set('ประเภทเนื้อหา', 'แอปพลิเคชัน/octet-stream');
ส่งคืน this.httpClient.post(this.host + '/entity/media', pdf, {ส่วนหัว: headers})
  .ท่อ(
    catchError(this.handleError<ใดๆ>('uploadMedia'))
);

ตรวจสอบหน้าบริการส่วนที่เหลือ ผู้ดูแลระบบ/config/services/restรูปแบบเนื้อหาที่อนุญาตคือ 'json'

การดีบักยืนยันว่า symfony กำลังตรวจสอบค่านี้

Symfony ยอมรับ JSON

ลองใช้อินเทอร์เฟซ REST เช่น '/jsonapi/media/document/field_media_document/'

ใช่ มีข้อกำหนดประเภทเนื้อหา 'bin' ใน web/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php ซึ่ง

// เพิ่มการตรวจสอบการเข้าถึงรูปแบบประเภทเนื้อหา สิ่งนี้จะบังคับใช้ทั้งหมด
// คำขอที่เข้ามาสามารถใช้ได้เฉพาะ 'application/octet-stream'
// ส่วนหัวของประเภทเนื้อหา

เดอะ /เอนทิตี/สื่อ URL คำขอ JSON API ไม่ต้องการคำขอ JSON ตาม เว็บ/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php

คำขอ json สื่อเอนทิตี

Score:0
ธง cn

ฉันใช้ Angular ไม่ใช่ React แต่ฉันค่อนข้างแน่ใจว่าส่วนนี้ผิด:

  // headers.set('Content-Type','application/octet-stream');
  headers.set('ประเภทเนื้อหา','application/hal+json');

ไฟล์จำเป็นต้องโพสต์เป็น แอปพลิเคชัน/ออคเต็ตสตรีม. ไม่ใช่วัตถุ JSON; มันเป็นไฟล์.

นอกจากนี้ คุณอาจต้องนวดข้อมูล PDF ให้เป็นสิ่งที่ JSON:API เข้าใจ ตัวอย่างเช่น, นี่คือเอกสารเกี่ยวกับการทำเช่นนี้กับ axios/Node.js.

ในกรณีของฉัน สำหรับไฟล์รูปภาพ ฉันต้องอ่านไฟล์เป็นหยด (โค้ดตอบกลับ แต่อาจให้ตัวอย่าง):

// https://stackoverflow.com/a/46568146
ฟังก์ชัน readFileBlob (fileBlob: Blob) {
  คืนสัญญาใหม่ ((แก้ไข) => {
    เครื่องอ่าน const = FileReader ใหม่ ();
    reader.onload = () => {
      แก้ไข (reader.result);
    };
    reader.onabort = () => Promise.reject (ข้อผิดพลาด ('การอ่านไฟล์ถูกยกเลิก'));
    reader.onerror = () => Promise.reject (ข้อผิดพลาด ('การอ่านไฟล์ล้มเหลว'));
    reader.readAsArrayBuffer (ไฟล์บล็อบ);
  });
}

// fileToPost เป็นสตริงที่มีหยด:
// หยด:http://localhost:8100/00507d3e-7f6f-4f48-be80-b55c8bc20dd3
const postAuthFileBlob = async (
  fetchUrl: สตริง
  fileToPost: สตริง
  // Fetch อาจส่งคืนอะไรก็ได้
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): สัญญา<ใดๆ> => {
  const fileBlob = รอการดึงข้อมูล (fileToPost) จากนั้น ((res) => res.blob ());
  const arrayStr = (รอ readFileBlob(fileBlob)) เป็น ArrayBuffer;
  ส่งคืน postAuthFileBlobPart2 (fetchUrl, arrayStr);
};
Interlated avatar
km flag
ฉันคิดว่าคุณอยู่ใกล้ ส่วนหลังบ่นว่าประเภทเนื้อหาเป็นแบบหลายส่วน/รูปแบบ-ข้อมูล แทนที่จะเป็นแอปพลิเคชัน/ออคเต็ตสตรีม
Interlated avatar
km flag
เพียงแค่โพสต์ pdf ให้ application/pdf ส่งคืน this.httpClient.post(this.host + '/entity/media', pdf, {headers: headers}) drupal ยังหาคู่สมัคร/pdf ไม่ได้ ไม่พบเส้นทางที่ตรงกับ "Content-Type: application/pdf" ใน Drupal\Core\Routing\ContentTypeHeaderMatcher->filter() (บรรทัดที่ 49 ของ
cn flag
@Interlated อย่างที่ฉันได้กล่าวไปแล้ว คุณต้องโพสต์เป็น `application/octet-stream` ด้วยเหตุผลบางอย่างที่คุณแสดงความคิดเห็นในรหัสของคุณ แต่คุณต้องโพสต์เป็น `application/octet-stream` หากคุณต้องการอัปโหลดไฟล์ไบนารี

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา