【内容运营项目】开发知识点&问题

115 阅读3分钟

axios请求数据使用qs.stringify(data)对数据进行转换,会自动过滤掉值为空数组[]的参数

处理方式:可将空数组值设置为null,stringify()过后key会存在,value为空,例如:arr=&keyword=123

function filterFunc(prefix, value) {
    if (isArray(value)&& value.length==0) {
        return null;
    }
    return value;
}
var myAjax = axios.create({
    timeout: 120000,
    transformRequest: [function(data) {
        // 对 data 进行任意转换处理
        if (isObject(data) && !(data instanceof FormData)) {
            // data = Qs.stringify(data);
            data = Qs.stringify(data, {filter: filterFunc} )
        }
        return data;
    }],
});

使用CryptoJS的AES方法对登录密码进行加密

后台对项目进行优化,与前端配合对登录密码进行加密:

image.png

  1. 安装 npm install crypto-js;
  2. 新建AES.js文件夹
import CryptoJS from 'crypto-js'; 
const KEY = '57*************4';

//AES加密
export const AES_Encrypt =(data) =>{
    //字符串类型的key用之前需要用uft8先parse一下才能用
    let key =  CryptoJS.enc.Utf8.parse(KEY);
    //由于后端使用的是PKCS5Padding,但是在使用CryptoJS的时候发现根本没有这个偏移,查询后发现PKCS5Padding和PKCS7Padding是一样的东东,使用时默认就是按照PKCS7Padding进行偏移的
    let encrypted = CryptoJS.AES.encrypt(data, key, {
        mode: CryptoJS.mode.ECB,
        padding:  CryptoJS.pad.Pkcs7,
    })
    return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(encrypted.ciphertext.toString()))
}

1. post请求报“请求的媒体类型不支持”

image.png

解决办法:根据Content-Type处理数据

var myAjax = axios.create({
    timeout: 120000,
    transformRequest: [function(data) {
        //(1) Content-Type:application/x-www-form-urlencoded
        // 对 data 进行任意转换处理
        // if (isObject(data) && !(data instanceof FormData)) {
        //     data = Qs.stringify(data);
        // }
        
        // (2) Content-Type:application/json
        data = JSON.stringify(data)
        return data;
    }],
});

2、阿里云数据存储

官网文档

  1. 安装 ali-oss: npm install ali-oss

3、编辑器editor请求时携带token

下载的是1.5.0版本的百度编辑器,源码修改参考文章

  1. 单文件上传:ueditor.all.js文件下查找到simpleupload函数, image.png

单文件上传用的form标签提交的,没法添加token,于是重写了提交方法:

image.png

callback()方法也需要修改:

image.png

  1. 视频、附件上传token,统一在dialogs文件夹下修改对应的文件即可;其他类似同理

image.png

遇到的其他问题: 原本外链引入ueditor相关资源,但是在点击编辑器的“视频、表情包等”工具栏的时候未出现内容且会弹出下载弹窗,最终发现时阿里云配置问题,由于不是本公司产品不方便配置,最终本地引入使用,问题解决。

image.png

image.png

ueditor.config.js配置:

image.png

4、通过正则获取后台返回富文本的图片链接并判断是否异步加载完成所有的图片

image.png

需求描述:使用百度文本编辑器导入文章内容,后台接口返回的内容其中图片是异步获取的,内容渲染到页面图片未加载出来,控制台报错404。

知识点

  1. 正则匹配内容获取所有图片链接
  2. head请求方法:检测图片资源在服务器是否存在,与get方法相同,只不过服务器响应时不会返回消息体。
  //通过文章链接-导入文章
  goImport() {
    const regex = /^(https?):\/\/[^\s/$.?#]*.[^\s]*$/i;
    if(!regex.test(this.formData.url)) {
      this.$message.error('请输入合理链接');
      return
    }
  //二次导入清空编辑器内容
    if(this.editUe && this.editUe.hasContents()){
      this.editUe.execCommand('cleardoc');
      let clearObj = {
        title: "",
        cover: "",
      }
      this.formData = Object.assign(this.formData, clearObj);
    }
    let params = {
      url: this.formData.url
    };
    this.loadNum = 0;
    timer = setInterval(()=> {
      if(this.loadNum<94){
        this.loadNum++;
      }
    }, 140)
    this.importFail = false;
    this.$ajax.post("/pm/get_article_content",params).then(({ status, data }) => {
      if (status == 200 && data.data.content) { 
        let resData = data.data;
        let articleMes = {
          cover: resData.cover,
          title: resData.title,
          content: resData.content,
        }
        this.formData.title = resData.title;
        //获取富文本所有图片链接
        //let regex = /<img.*? src="(.*?)".*?>/g;
        //获取富文本所有图片&视频链接
        let regex = /"(https:\/\/[^"]+\.oss-cn-beijing.aliyuncs.com\/[^"]+)"/g;
        let matchArr = null;
        const imgUrls = [];
        // 获取富文本所有图片链接
        while ((matchArr = regex.exec(resData.content)) !== null) {
          imgUrls.push(matchArr[1]);
        }
        this.judgeImgsGeted(imgUrls, articleMes);
      }else {
        this.importFail = true;
        this.$util.toast("获取文章内容失败");
      }
    })
    .catch(err=> {
      this.importFail = true;
      clearInterval(timer);
      for(let timerKey in intervalTimer) {
        clearInterval(timerKey);
      }
      this.$util.toastError(err);
    })
    .finally(()=> {
    });
  },
  //封面图--判断是否拿到
  judgeImgsGeted(imgUrls, articleMes) {
    let loadSuccessNum = 0;
    let loadFailNum = 0;
    //封面图
    if(articleMes.cover) imgUrls.push(articleMes.cover);
    let imgLen = imgUrls.length;
    if(imgLen== 0) return
    // console.log("图片长度---", imgLen);
    imgUrls.forEach((item, index)=> {
      intervalTimer[index+1] = setInterval(()=> {
        this.$ajax.head(item).then(res=> {
          clearInterval(intervalTimer[index+1]);
          ++loadSuccessNum;
          if(loadSuccessNum == imgLen) {
            this.insertContent(articleMes);
          }
        }).catch(err=> {
          if(err && err.response && err.response.status == 404){
            return
          }else {
            console.log("失败---***----", index, item)
            ++loadFailNum;
            clearInterval(intervalTimer[index+1]);
          }
        }).finally(res => {
          if(loadFailNum && loadSuccessNum + loadFailNum == imgLen) {
            this.insertContent(articleMes);
          }
        });
      }, 2500)
    })
  },
  // 插入文本内容
  insertContent(articleMes) {
    this.loadNum = 100;
    clearInterval(timer);
    articleMes.cover && (this.formData.cover = articleMes.cover);
    UE.getEditor('container').execCommand('insertHtml', articleMes.content);   
  },