使用@wangeditor/editor-for-react实现 React项目跨域跨端口跟Vue项目共享token

vue项目中:
axios.defaults.withCredentials
withCredentials:默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据。

默认值为false。
true:在跨域请求时,会携带用户凭证
false:在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie
当配置了 withCredentials = true时,必须在后端增加 response 头信息Access-Control-Allow-Origin,且必须指定域名,而不能指定为*

如果后端需要带cookie过去,前端需要设置为true

Vue中的代码

const http = axios.create({
  baseURL: process.env.VUE_APP_API_URL,
  timeout: 1000 * 180,
  withCredentials: true,
})

React中的代码

MyEditor.tsx

 const MyEditorRef: any = useRef(null);
  useImperativeHandle(ref, () => {
    return {
     
    };
  });
  // 模拟 ajax 请求,异步设置 html
  useEffect(() => {
    setHtml(html);
  }, [html]);
  useEffect(() => {
    setHtml(props?.newsHtml ? props?.newsHtml : html);
    setReadyOnly(props?.readyOnlyEdit ? props?.readyOnlyEdit : false);
  }, [props]);
  // 及时销毁 editor
  useEffect(() => {
    return () => {
      if (editor == null) return;
      editor.destroy();
      setEditor(null);
    };
  }, [editor]);
  const insertText = () => {
    if (editor == null) return;
    editor.insertText(' hello ');
  };

  const printHtml = () => {
    if (editor == null) return;
    console.log(editor.getHtml());
  };
  const customCheckVideoFn = (src, poster) => {
    // TS 语法
    // function customCheckVideoFn(src, poster) {                                             // JS 语法
    if (!src) {
      return;
    }
    if (src.indexOf('http') !== 0) {
      return '视频地址必须以 http/https 开头';
    }
    return true;

    // 返回值有三种选择:
    // 1. 返回 true ,说明检查通过,编辑器将正常插入视频
    // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
    // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
  };
  const toolbarConfig = {};
  let editorConfig = {
    // placeholder: props?.readyOnly ? '' : '请输入内容...',
    MENU_CONF: {},
    readOnly: true,
    autoFocus: false,
  };
   // 自定义转换视频
   const customParseVideoSrc = (src) => {
    // TS 语法
    // function customParseVideoSrc(src) {               // JS 语法
    if (src.includes('.bilibili.com')) {
      // 转换 bilibili url 为 iframe (仅作为示例,不保证代码正确和完整)
      const arr = location.pathname.split('/');
      const vid = arr[arr.length - 1];
      return `<iframe src="//player.bilibili.com/player.html?bvid=${vid}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>`;
    }
    return src;
  };
  editorConfig.MENU_CONF['uploadImage'] = {
    // 上传图片的配置
    // server: `${API.uploadNoticeFile}`,
    // form-data fieldName ,默认值 'wangeditor-uploaded-image'
    fieldName: 'file',
    // 单个文件的最大体积限制,默认为 2M
    maxFileSize: 1 * 1024 * 1024, // 1M
    // 最多可上传几个文件,默认为 100
    maxNumberOfFiles: 10,
    // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
    allowedFileTypes: ['image/*'],
    // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
    meta: {
      // token: 'xxx',
      pathIndex: 1 
    },

    // 将 meta 拼接到 url 参数中,默认 false
    metaWithUrl: false,

    // 自定义增加 http  header
    // headers: {
    //   Accept: 'application/json',
    //   Authorization: `Bearer ${accessToken}`,
    //   'X-SAAS-Tenant-ID': tenantId,
    //   'X-SAAS-DEBUG': true,
    //   'X-SAAS-User-ID': useId,
    // },

    // 跨域是否传递 cookie ,默认为 false
    withCredentials: true,

    // 超时时间,默认为 10 秒
    timeout: 5 * 1000, // 5 秒
    // 上传之前触发

    onBeforeUpload(file) {
      // editor.initSelection()

      // TS 语法
      // onBeforeUpload(file) {    // JS 语法
      // file 选中的文件,格式如 { key: file }
      console.log('file', file);
      return file;
      // editorRef.current.editor.cmd.do('insertHtml', `<img src="${imageUrl}" alt=""/>`);
      // 可以 return
      // 1. return file 或者 new 一个 file ,接下来将上传
      // 2. return false ,不上传这个 file
    },

    // 上传进度的回调函数
    onProgress(progress:any) {
      // TS 语法
      // onProgress(progress) {       // JS 语法
      // progress 是 0-100 的数字
      console.log('progress', progress);
    },
    // 自定义插入图片
    customInsert(res:any, insertFn:any) {
      console.log('insertFn', res, insertFn);
      // TS 语法
      // customInsert(res, insertFn) {                  // JS 语法
      // res 即服务端的返回结果
      if ('00000' == res.code) {
        let { url, filename } = res.data;
        // 从 res 中找到 url alt href ,然后插入图片
        // insertFn(url);
        insertFn(url, filename, url);
      }
    },
  };
  editorConfig.MENU_CONF['insertVideo'] = {
    onInsertedVideo(videoNode:any) {
      // TS 语法
      // onInsertedVideo(videoNode) {                    // JS 语法
      if (videoNode == null) return;

      const { src } = videoNode;
      console.log('inserted video', src);
    },
    checkVideo: customCheckVideoFn, // 也支持 async 函数
    parseVideoSrc: customParseVideoSrc, // 也支持 async 函数
  };

  return (
    <>
      <div
        style={{ zIndex: 100, marginTop: '15px' }}
        className={styles[readyOnly ? '' : 'borders']}
      >
        {!readyOnly && (
          <Toolbar
            editor={editor}
            defaultConfig={toolbarConfig}
            mode="default"
            style={{ borderBottom: '1px solid #ccc' }}
          />
        )}
        <Editor
          
          ref={editor}
          defaultConfig={editorConfig}
          value={html}
          onChange={(editor) => {
            setHtml(editor.getHtml());
            props.setEditorFun(editor.getHtml());
          }}
          mode="default"
      
        />
      </div>
    </>
  );
})
);


备注:
感谢大家的耐心阅读,如果有任何问题或者建议,欢迎在评论区留言。有不懂的可以评论区留言,或者私聊我,知无不言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容