如何接收上传图片的 URL 并将其传递给 CK Editor 中的 "src" 属性?

How to receive the URL of uploaded image and pass it to "src" attribute in CK Editor?

Base64 image upload adapter一样,CKEditor对图片进行明显的编码,转为Base64格式,然后插入结果为<img src="data:image/png;base64, code... >。代码可能很长;我想要上传的图片 URL。

在我的应用程序中,我需要以下功能:

  1. 将图像转换为 Base64。我基本上知道怎么做:
async function encodeSingleFileTo64base(targetFile: File): Promise<string> {

  const fileReader: FileReader = new FileReader();

  fileReader.readAsDataURL(targetFile);
  
  return new Promise<string>((resolve: (encodedFile: string) => void, reject: (error: Error) => void): void => {
    fileReader.onload = (filedHasBeenReadEvent: ProgressEvent<FileReader>): void => {
      if (filedHasBeenReadEvent.target === null || filedHasBeenReadEvent.target.result === null) {
        reject(new Error("Failed to encode the image file."));
        return;
      }
      resolve(String(filedHasBeenReadEvent.target.result));
    };
  });
}
  1. 通过 GraphQL 提交 Base64 代码。我基本可以:
import AWSAmplifyAPI, { graphqlOperation, GraphQLResult } from "@aws-amplify/api";

async function uploadPhotoAndGetURL(photoBase64: string): Promise<string> {
  return (await AWSAmplifyAPI.graphql(graphqlOperation(
    `mutation($photoBase64: String!) { uploadPhoto(photoBase64: $photoBase64) }`, 
    { photoBase64 }
  ))).uploadPhoto;  
}
  1. 让 CK 编辑器将收到的响应 URL 添加到 src=""(这是当前问题的主题)。

这是来自 documentation 的解决方案模板:

class MyUploadAdapter {

  constructor( loader ) {
      this.loader = loader;
  }

  
  upload() {
      return loader.file
          .then( file => server.upload( file ) );
  }

 
  abort() {
      server.abortUpload();
  }
}

第一个问题:如何在 upload() 方法中链接两个异步函数?

编码和数据提交都是异步操作。 我一直很困惑如何与 loader.file.then().

兼容

第二个问题:如何将收到的URL传递给CK编辑器?

我无法从建议的解决方案模板中理解我们如何接收上传的图像 URL 并将其传递给 src 属性。

First problem: how to chain two async functions in upload() method?

从这里开始:https://thoughtbot.com/blog/chaining-events-like-a-boss

示例:

const timeUserRequest = async () => {
  const before = await getCurrentTimeAsync()
  await getUserDataViaHttp()
  const after = await getCurrentTimeAsync()

  return (after - before)
};

Second problem: how to pass recieved URL to CK editor?

您是如何提出请求的?你看到这个例子了吗?

class MyUploadAdapter {
    // ...

    // Initializes XMLHttpRequest listeners.
    _initListeners( resolve, reject, file ) {
        const xhr = this.xhr;
        const loader = this.loader;
        const genericErrorText = `Couldn't upload file: ${ file.name }.`;

        xhr.addEventListener( 'error', () => reject( genericErrorText ) );
        xhr.addEventListener( 'abort', () => reject() );
        xhr.addEventListener( 'load', () => {
            const response = xhr.response;

            // This example assumes the XHR server's "response" object will come with
            // an "error" which has its own "message" that can be passed to reject()
            // in the upload promise.
            //
            // Your integration may handle upload errors in a different way so make sure
            // it is done properly. The reject() function must be called when the upload fails.
            if ( !response || response.error ) {
                return reject( response && response.error ? response.error.message : genericErrorText );
            }

            // If the upload is successful, resolve the upload promise with an object containing
            // at least the "default" URL, pointing to the image on the server.
            // This URL will be used to display the image in the content. Learn more in the
            // UploadAdapter#upload documentation.
            resolve( {
                default: response.url
            } );
        } );

        // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
        // properties which are used e.g. to display the upload progress bar in the editor
        // user interface.
        if ( xhr.upload ) {
            xhr.upload.addEventListener( 'progress', evt => {
                if ( evt.lengthComputable ) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            } );
        }
    }
}