AntD框架的upload组件上传图片时遇到的一些坑

千古壹号 2019-03-02 21:49:00 阅读数:175 评论数:0 收藏数:0

前言

本次做后台管理系统,采用的是 AntD 框架。涉及到图片的上传,用的是AntD的 upload 组件。

前端做文件上传这个功能,是很有技术难度的。既然框架给我们提供好了,那就直接用呗。结果用的时候,发现 upload 组件的很多bug。下面来列举几个。

备注:本文写于2019-03-02,使用的 antd 版本是 3.13.6。

使用 AntD 的 upload 组件做图片的上传

因为需要上传多张图片,所以采用的是照片墙的形式。上传成功后的界面如下:

(1)上传中:

(2)上传成功:

(3)图片预览:

按照官方提供的实例,特此整理出项目开发中的完整写法,亲测有效。代码如下:

/* eslint-disable */

import { Upload, Icon, Modal, Form } from 'antd';

const FormItem = Form.Item;

class PicturesWall extends PureComponent {
  state = {
    previewVisible: false,
    previewImage: '',
    imgList: [],
  };


  handleChange = ({ file, fileList }) => {
    console.log(JSON.stringify(file)); // file 是当前正在上传的 单个 img
    console.log(JSON.stringify(fileList)); // fileList 是已上传的全部 img 列表

    this.setState({
      imgList: fileList,
    });
  };


  handleCancel = () => this.setState({ previewVisible: false });

  handlePreview = file => {
    this.setState({
      previewImage: file.url || file.thumbUrl,
      previewVisible: true,
    });
  };


  // 参考链接:https://www.jianshu.com/p/f356f050b3c9
  handleBeforeUpload = file => {
    //限制图片 格式、size、分辨率
    const isJPG = file.type === 'image/jpeg';
    const isJPEG = file.type === 'image/jpeg';
    const isGIF = file.type === 'image/gif';
    const isPNG = file.type === 'image/png';
    if (!(isJPG || isJPEG || isGIF || isPNG)) {
      Modal.error({
        title: '只能上传JPG 、JPEG 、GIF、 PNG格式的图片~',
      });
      return;
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      Modal.error({
        title: '超过2M限制 不允许上传~',
      });
      return;
    }
    return (isJPG || isJPEG || isGIF || isPNG) && isLt2M && this.checkImageWH(file);
  };

  //返回一个 promise:检测通过则返回resolve;失败则返回reject,并阻止图片上传
  checkImageWH(file) {
    let self = this;
    return new Promise(function(resolve, reject) {
      let filereader = new FileReader();
      filereader.onload = e => {
        let src = e.target.result;
        const image = new Image();
        image.onload = function() {
          // 获取图片的宽高,并存放到file对象中
          console.log('file width :' + this.width);
          console.log('file height :' + this.height);
          file.width = this.width;
          file.height = this.height;
          resolve();
        };
        image.onerror = reject;
        image.src = src;
      };
      filereader.readAsDataURL(file);
    });
  }

  handleSubmit = e => {
    const { dispatch, form } = this.props;
    e.preventDefault();
    form.validateFieldsAndScroll((err, values) => {// values 是form表单里的参数
      // 点击按钮后,将表单提交给后台
      dispatch({
        type: 'mymodel/submitFormData',
        payload: values,
      });
    });
  };

  render() {
    const { previewVisible, previewImage, imgList } = this.state; //  从 state 中拿数据
    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
    return (
      <div className="clearfix">
        <Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
          <FormItem label="图片图片" {...formItemLayout}>
            {getFieldDecorator('myImg')(
              <Upload
                action="//jsonplaceholder.typicode.com/posts/" // 这个是接口请求
                data={file => ({ // data里存放的是接口的请求参数
                  param1: myParam1,
                  param2: myParam2,
                  photoCotent: file, // file 是当前正在上传的图片
                  photoWidth: file.height, // 通过  handleBeforeUpload 获取 图片的宽高
                  photoHeight: file.width,
                })}
                listType="picture-card"
                fileList={this.state.imgList}
                onPreview={this.handlePreview} // 点击图片缩略图,进行预览
                beforeUpload={this.handleBeforeUpload} // 上传之前,对图片的格式做校验,并获取图片的宽高
                onChange={this.handleChange} // 每次上传图片时,都会触发这个方法
              >
                {this.state.imgList.length >= 9 ? null : uploadButton}
              </Upload>
            )}
          </FormItem>
        </Form>
        <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </div>
    );
  }
}

export default PicturesWall;

上传后,点击图片预览,浏览器卡死的问题

依据上方的代码,通过 Antd 的 upload 组件将图片上传成功后,点击图片的缩略图,理应可以在当前页面弹出 Modal,预览图片。但实际的结果是,浏览器一定会卡死。

定位问题发现,原因竟然是:图片上传成功后, upload 会将其转为 base64编码。base64这个字符串太大了,点击图片预览的时候,浏览器在解析一大串字符串,然后就卡死了。详细过程描述如下。

上方代码中,我们可以把 handleChange(file, fileList)方法中的 file、以及 fileList打印出来看看。 file指的是当前正在上传的 单个 img,fileList是已上传的全部 img 列表。 当我上传完 两张图片后, 打印结果如下:

file的打印的结果如下:

    {
        "uid": "rc-upload-1551084269812-5",
        "width": 600,
        "height": 354,
        "lastModified": 1546701318000,
        "lastModifiedDate": "2019-01-05T15:15:18.000Z",
        "name": "e30e7b9680634b2c888c8bb513cc595d.jpg",
        "size": 31731,
        "type": "image/jpeg",
        "percent": 100,
        "originFileObj": {
            "uid": "rc-upload-1551084269812-5",
            "width": 600,
            "height": 354
        },
        "status": "done",
        "thumbUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAHQ9qKKlbimcXrIH9o2vH/AC2T+ddPj98v+9RRWsuhnHdk0ar9qb5R0Pb6VPB/qh9aKKiRr0Irnt/vUDr+NFFJCRqWxJik5Pb+dLJ938aKK06mYSdKKKKBH//Z",
        "response": {
            "retCode": 0,
            "imgUrl": "http://qianguyihao.com/opfewfwj098902kpkpkkj976fe.jpg",
            "photoid": 271850
        }
    }

fileList 的打印结果:

[
    {
        "uid": "rc-upload-1551084269812-3",
        "width": 1000,
        "height": 667,
        "lastModified": 1501414799000,
        "lastModifiedDate": "2017-07-30T11:39:59.000Z",
        "name": "29381f30e924b89914e91b33.jpg",
        "size": 135204,
        "type": "image/jpeg",
        "percent": 100,
        "originFileObj": {
            "uid": "rc-upload-1551084269812-3",
            "width": 1000,
            "height": 667
        },
        "status": "done",
        "thumbUrl": "data:image/jpeg;base64,/E3ju1tlaK1fzJOnHQU3LsLV7HO6Zrk11MZJ7luT0A4FZuRagi9quvzQQ4iuEJ7ZpqTG4djDsPFl2Lg733f8C4q+YhQ8zoYfGSqoMmfwo5huLL0HjiyPDSYPvxRdC1XQvxeLrB8fvl/OnoLmL9vrdvvYS3NGFVe2YsASOh71JfQyrqV2mXLHOcccVSIYEnDyZO9XXB9KYH//Z",
        "response": {
            "retCode": 0,
            "msg": "success",
            "imgUrl": "http://qianguyihao.com/hfwpjouiurewnmbhepr689.jpg",
        }
    },
    {
        "uid": "rc-upload-1551084269812-5",
        "width": 600,
        "height": 354,
        "lastModified": 1546701318000,
        "lastModifiedDate": "2019-01-05T15:15:18.000Z",
        "name": "e30e7b9680634b2c888c8bb513cc595d.jpg",
        "size": 31731,
        "type": "image/jpeg",
        "percent": 100,
        "originFileObj": {
            "uid": "rc-upload-1551084269812-5",
            "width": 600,
            "height": 354
        },
        "status": "done",
        "thumbUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAHQ9qKKlbimcXrIH9o2vH/AC2T+ddPj98v+9RRWsuhnHdk0ar9qb5R0Pb6VPB/qh9aKKiRr0Irnt/vUDr+NFFJCRqWxJik5Pb+dLJ938aKK06mYSdKKKKBH//Z",
        "response": {
            "retCode": 0,
            "imgUrl": "http://qianguyihao.com/opfewfwj098902kpkpkkj976fe.jpg",
            "photoid": 271850
        }
    }
]

上方的json数据中,需要做几点解释:

(1)response 字段里面的数据,就是请求接口后,后台返回给前端的数据,里面包含了图片的url链接。

(2)status 字段里存放的是图片上传的实时状态,包括上传中、上传完成、上传失败。

(3)thumbUrl字段里面存放的是图片的base64编码。

这个base64编码非常非常长。当点击图片预览的时候,其实就是加载的 thumbUrl 这个字段里的资源,难怪浏览器会卡死。

解决办法:在 handleChange方法里,图片上传成功后,将 thumbUrl 字段里面的 base64 编码改为真实的图片url。代码实现如下:

  handleChange = ({ file, fileList }) => {
    console.log(JSON.stringify(file)); // file 是当前正在上传的 单个 img
    console.log(JSON.stringify(fileList)); // fileList 是已上传的全部 img 列表

    if (file && file.response && file.response.retCode == 0) {
      console.log('图片上传成功');
      fileList.forEach(item => {
        // 【重要】将 图片的base64替换为图片的url。 这一行一定不会能少。
        // 图片上传成功后,fileList数组中的 thumbUrl 中保存的是图片的base64字符串,这种情况,导致的问题是:图片上传成功后,点击图片缩略图,浏览器会会卡死。而下面这行代码,可以解决该bug。
        item.thumbUrl = item.response.imgUrl;
      });
    }

    this.setState({
      imgList: fileList,
    });
  };

新需求:编辑现有页面

上面一段的代码中,我们是在新建的页面中,从零开始上传图片。

现在有个新的需求:如何编辑现有的页面呢?也就是说说,现有的页面中,是默认有几张图片的。当我编辑这个页面时,可以对现有的图片做增删,也能增加新的图片。

我看到upload 组件有提供 defaultFileList 的属性。我试了下,这个defaultFileList 的属性根本没法儿用。

那就只要手动实现了。我的model层代码,是用 redux 写的。实现思路如下:

(1)PicturesWall.js:

/* eslint-disable */

import { Upload, Icon, Modal, Form } from 'antd';

const FormItem = Form.Item;

class PicturesWall extends PureComponent {
  state = {
    previewVisible: false,
    previewImage: '',
  };

  // 页面初始化的时候,从接口拉取默认的图片数据
  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'mymodel/getAllInfo',
      payload: { params: xxx },
    });
  }

  handleChange = ({ file, fileList }) => {
    const { dispatch } = this.props;
    if (file && file.response && file.response.retCode == 0) {
      console.log('图片上传成功');
      fileList.forEach(item => {
        // 【重要】将 图片的base64替换为图片的url。 这一行一定不会能少。
        // 图片上传成功后,fileList数组中的 thumbUrl 中保存的是图片的base64字符串,这种情况,导致的问题是:图片上传成功后,点击图片缩略图,浏览器会会卡死。而下面这行代码,可以解决该bug。
        item.thumbUrl = item.response.imgUrl;
      });
    }

    dispatch({
      type: 'mymodel/setImgList',
      payload: fileList,
    });
  };

  handleCancel = () => this.setState({ previewVisible: false });

  handlePreview = file => {
    this.setState({
      previewImage: file.url || file.thumbUrl,
      previewVisible: true,
    });
  };

  // 参考链接:https://www.jianshu.com/p/f356f050b3c9
  handleBeforeUpload = file => {
    //限制图片 格式、size、分辨率
    const isJPG = file.type === 'image/jpeg';
    const isJPEG = file.type === 'image/jpeg';
    const isGIF = file.type === 'image/gif';
    const isPNG = file.type === 'image/png';
    if (!(isJPG || isJPEG || isGIF || isPNG)) {
      Modal.error({
        title: '只能上传JPG 、JPEG 、GIF、 PNG格式的图片~',
      });
      return;
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      Modal.error({
        title: '超过2M限制 不允许上传~',
      });
      return;
    }
    return (isJPG || isJPEG || isGIF || isPNG) && isLt2M && this.checkImageWH(file);
  };

  //返回一个 promise:检测通过则返回resolve;失败则返回reject,并阻止图片上传
  checkImageWH(file) {
    let self = this;
    return new Promise(function(resolve, reject) {
      let filereader = new FileReader();
      filereader.onload = e => {
        let src = e.target.result;
        const image = new Image();
        image.onload = function() {
          // 获取图片的宽高,并存放到file对象中
          console.log('file width :' + this.width);
          console.log('file height :' + this.height);
          file.width = this.width;
          file.height = this.height;
          resolve();
        };
        image.onerror = reject;
        image.src = src;
      };
      filereader.readAsDataURL(file);
    });
  }

  handleSubmit = e => {
    const { dispatch, form } = this.props;
    e.preventDefault();
    form.validateFieldsAndScroll((err, values) => {
      // values 是form表单里的参数
      // 点击按钮后,将表单提交给后台
      dispatch({
        type: 'mymodel/submitFormData',
        payload: values,
      });
    });
  };

  render() {
    const { previewVisible, previewImage } = this.state; //  从 state 中拿数据

    const {
      mymodel: { imgList }, // 从props中拿到的图片数据
    } = this.props;

    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
    return (
      <div className="clearfix">
        <Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
          <FormItem label="图片上传" {...formItemLayout}>
            {getFieldDecorator('myImg')(
              <Upload
                action="//jsonplaceholder.typicode.com/posts/" // 这个是接口请求
                data={file => ({
                  // data里存放的是接口的请求参数
                  param1: myParam1,
                  param2: myParam2,
                  photoCotent: file, // file 是当前正在上传的图片
                  photoWidth: file.height, // 通过  handleBeforeUpload 获取 图片的宽高
                  photoHeight: file.width,
                })}
                listType="picture-card"
                fileList={imgList}  // 改为从 props 里拿图片数据,而不是从 state
                onPreview={this.handlePreview} // 点击图片缩略图,进行预览
                beforeUpload={this.handleBeforeUpload} // 上传之前,对图片的格式做校验,并获取图片的宽高
                onChange={this.handleChange} // 每次上传图片时,都会触发这个方法
              >
                {this.state.imgList.length >= 9 ? null : uploadButton}
              </Upload>
            )}
          </FormItem>
        </Form>
        <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </div>
    );
  }
}

export default PicturesWall;

(2)mymodel.js:

/* eslint-disable */

import { routerRedux } from 'dva/router';
import { message, Modal } from 'antd';
import {
  getTuanList,
  getAllFactory,
  getAllFactGoods,
  createFactShop,
  updateFactShop,
  deleteFactShop,
  updateFactGoodsStatus,
  queryShopDetail,
  createFactGoods,
} from '../services/api';
import { trim, getCookie } from '../utils/utils';

export default {
  namespace: 'factory',

  state: {
    form: {},
    list: [],
    listDetail: [],
    goodsList: [],
    goodsListDetail: [],
    pagination: {
      pageSize: 10,
      total: 0,
      current: 1,
    },
    imgList: [], //图片
  },
  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(location => {
        if (location.pathname !== '/xx/xxx') return;
        if (!location.state || !location.state.xxxId) return;
        dispatch({
          type: 'fetch',
          payload: location.state,
        });
      });
    },
  },

  effects: {
    // 接口。获取所有工厂店的列表 (步骤02)
    *getAllInfo({ payload }, { select, call, put }) {
      yield put({
        type: 'form',
        payload,
      });
      console.log('params:' + JSON.stringify(payload));

      let params = {};
      params = payload;

      const response = yield call(getAllFactory, params);

      console.log('smyhvae response:' + JSON.stringify(response));
      if (response.error) return;
      yield put({
        type: 'allInfo',
        payload:
          (response.data &&
            response.data.map(item => ({
              xx1: item.yy1,
              xx2: item.yy2,
            }))) ||
          [],
      });

      // response 里包含了接口返回给前端的默认图片数据
      if (response && response.data && response.data[0] && response.data[0].my_jpg) {
        let tempImgList = response.data[0].my_jpg.split(',');
        let imgList = [];

        if (tempImgList.length > 0) {
          tempImgList.forEach(item => {
            imgList.push({
              uid: item,
              name: 'xxx.png',
              status: 'done',
              thumbUrl: item,
            });
          });
        }

        // 通过  redux的方式 将 默认图片 传给 imgList
        console.log('smyhvae payload imgList:' + JSON.stringify(imgList));
        yield put({
          type: 'setImgList',
          payload: imgList,
        });
      }
    },

    *setImgList({ payload }, { call, put }) {
      console.log('smyhvae model setImgList');
      yield put({
        type: 'getImgList',
        payload,
      });
    },
  },

  reducers: {
    allInfo(state, action) {
      return {
        ...state,
        list: action.payload,
      };
    },
    getImgList(state, action) {
      return {
        ...state,
        imgList: action.payload,
      };
    },
  },
};

大功告成。

本文感谢 ld 同学的支持。

最后一段

有人说,前端开发,连卖菜的都会。可如果真的遇到技术难题,还是得找个靠谱的前端同学才行。这不,来看看前端码农日常:


版权声明:本文为[千古壹号]原创文章
转载请带上:http://copyfuture.com/blogs-details/06a0e0a96110cb049bac61c6d38a2ec6
或:https://www.cnblogs.com/qianguyihao/p/10460834.html


  1. 海军终于有了自己的轰-6J,这种设想多年的战术终于可以实现了!
  2. CAS实现SSO单点登录原理
  3. Python 增加博客园阅读量
  4. 山上常见的这种植物,还是中药一味,你知道吗
  5. 世界两大阵营呼之欲出,一个是“五眼联盟”,一个是“无眼联盟”
  6. “洞察”号变身火星天气报告员
  7. 2019-01-06 昨天发生了什么
  8. 常用正则表达式整理
  9. 收好这份北京门头沟赏花攻略!山谷花海,心动吗?
  10. 心脑血管疾病患者突然体力大降时,应高度警惕发生心衰
  11. 企业微信的菜单管理
  12. Leetcode 1-10
  13. 中央纪委两条消息背后的大动作
  14. 银河系中心并非球形!立体拆解太阳在银河中的位置,邻居都是谁?
  15. 微软确认新的Windows 10累积更新问题 建议完全重置系统
  16. 真爱不婚,出道夺金像却成TVB绿叶女王,最灵阿紫战胜抑郁自璀璨
  17. 马刺八连胜!要说说讨厌波波维奇的理由,还真可以讲很多……
  18. 拿着1万块人民币,去俄罗斯能生活多久?游客:跟你想的可能不同
  19. 埃塞客机黑匣子数据已下载 坠毁前细节曝光
  20. 央视3·15曝光的AI机器人推销电话公司 采用了什么核心技术?
  21. 卫视热播《都挺好》大结局-原书无删减版剧透-情节102
  22. 假如美团做社交
  23. 刚刚传回的火星消息!洞察号首次在火星地表探测到嗡嗡声!
  24. 《你的歌曲》将经典怀旧与纪实相结合,私人化的讲述视角值得关注
  25. 迪拜人到底有多“壕”?看到汉堡里的肉,肯德基:告辞
  26. 清空与张丹峰合影的48岁洪欣,凭什么被她嘲笑成老女人?
  27. CSGO外挂的初步制作,Cheatengine使用
  28. 仅次于B2的重型轰炸机“重出江湖”重量可比4架轰6
  29. 重拾《 两周自制脚本语言 》- 支持中文标识符
  30. 这些风华绝代的国货,有你pick的那款吗!
  31. 《圣歌》——落后于时代的美丽新世界
  32. 青春斗发布会:赵宝刚谈郑爽演技炸裂!男女比例3:1感情线成亮点
  33. 心脏支架后,咳嗽一下支架能脱落吗?需要注意什么?
  34. 科学家沸腾了!两万八千年前的猛犸象DNA被短暂“唤醒”!
  35. 瞒不住了!丑陋的波音,是如何成为“空中屠夫”的?
  36. 恐龙灭绝时的场景再现?科学家:小行星坠落地面后还在“动”
  37. 习题练习(二)
  38. 齐达内回归皇马!伯纳乌迎回传奇教头并翻开新的的篇章!
  39. 女神张敏:用最好的资源做了最差的选择,51岁复出是为何
  40. “插座一哥”摊上事被诉赔10亿 其创始人身家超400亿
  41. Python数据可视化之Matplotlib实现各种图表
  42. 新型空气极材料可用于固体燃料电池
  43. Stream流
  44. 关于重力和引力那些不为人知的事实
  45. 印度与巴基斯坦前世今生的仇恨
  46. 我眼中的 Nginx(三):Nginx 变量和变量插值
  47. 即日起,这4种车将不能上牌,新能源车牌指标也将收紧?
  48. 315诚信季:电商的页面宣传,价格特惠,你被套路了吗?
  49. 上饶警方:10岁男生在校内被女同学家长刺死,嫌疑人被控制
  50. 8款开源好用的网上电子商城系统介绍
  51. JAVA商城项目(微服务框架)——第17天 授权中心
  52. 【OpenCV3】cvRound()、cvFloor()、cvCeil()函数详解
  53. 姜丹尼尔认了「IG遭控制」 决裂公司:我会重新办帐号
  54. 团车第四季度净亏损430万美元 亏损幅度同比扩大
  55. 超类地行星是否适合居住仍无解,我们还是保护地球生态环境吧
  56. 二战中“最冤”的苏联师长,因丢掉了55个野战厨房,被斯大林处决
  57. 不止手机 三星半导体市场龙头地位或也将让位英特尔
  58. 以网络服务切入,高通也加入智能家居混战
  59. 以史为鉴,一轮牛市结束的十大信号!
  60. 如何获取免版权图片资源
  61. 苹果、微软为何能够二次崛起?
  62. 你家宝宝是不是更喜欢被竖着抱?没到这个月,宝妈可要抗住了!
  63. 宇宙是真空,没有氧气,太阳为什么会燃烧?
  64. 奥斯曼帝国的终结:病夫的末日
  65. Javascript高级编程学习笔记(63)—— 事件(7)鼠标及滚轮事件
  66. 使用wireshark抓取ICMP流量包并分析ICMP协议
  67. 2019看清生命清单
  68. 解决 APP启动白屏黑屏问题
  69. 【原创】如何用面向对象思想编写代码
  70. 全栈程序员应该学习的都在这里
  71. C# explicit interface implementation(显式接口实现)
  72. 立陶宛记者:NBA多队有意莫泰 后者收到一份CBA球队报价
  73. 不看实车看视频买异地二手车靠谱么?
  74. 勇士拒绝横扫阻截火箭9连胜,休城就凭1招鲜火拼5巨头
  75. 歌手郑智化发文称台湾省已原地踏步20年、痛心有太多“井底之蛙”
  76. 10条朋友圈最近蛮火的句子,我没有取悦你的天分,但我比谁都认真
  77. Nature子刊:40%疾病源于基因,25%与环境有关
  78. 在美国枪支被当作商品买卖,为何还能保持稳定,因为有个厉害部门
  79. 巴黎秘密之旅:这些地方你一定要去!
  80. 多证件识读仪是如何广泛应用的
  81. 程序员上班刷简历!领导看见表示寒心竟还想挽留:别耽误人家
  82. 张嘉倪的嘴,骗人的鬼
  83. 为何王牌之师维京师,坚决不向苏联人投降,强行突围到美控制区?
  84. [翻译] 使用 .NET Core 3.0 创建一个 Windows 服务
  85. IPv6的NAT原理以及MAP66
  86. 韩国姓氏来源于哪里?有三个途径,最后一点他们必须承认
  87. 在编写Arcgis Engine 过程中对于接口引用和实现过程过产生的感悟
  88. 世界上首款三波段雷达护卫舰,排水量仅3600吨,最大射程40公里
  89. 观察+ | 拼多多不必追赶淘宝京东,C2M模式更有想象力
  90. [Java初探外篇]__关于时间复杂度与空间复杂度
  91. 微软云计算现隐忧:一季度增速下滑至73% 去年四季度为76%
  92. 长安前2月销量下跌28.32% 急需走量新车而不是自嗨营销
  93. 巨亏的滴滴,再获软银16亿美元融资!为啥孙正义就这么看好滴滴?
  94. 有哪些简短而又深情的告白句子?
  95. 飞絮作妖,难道就没有办法治治它们?
  96. 不负春光一日醉
  97. swagger使用指南
  98. 死磕 java同步系列之synchronized解析
  99. 谁说有糖尿病就不能吃水果?!
  100. 如何一步步使用国内yum源一键安装openstack-ocata版本基于centos7

  1. Python开发:部分第三方库无法在线安装解决方法(949)
  2. [Swift]LeetCode325. 最大子数组之和为k $ Maximum Size Subarray Sum Equals k(779)
  3. Matlab 2019a 安装包下载以及安装和激活(720)
  4. 仅限Edge和Chrome访问 全新网页端Skype应用上线(686)
  5. 前端笔记之NodeJS(一)初识NodeJS&内置模块&特点(684)
  6. C#读取excel文件提示未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序(663)
  7. 【预警通告】Weblogic反序列化远程代码执行漏洞(640)
  8. Visual Studio 2019 正式发布,重磅更新,支持live share(600)
  9. 【预警通告】Apache Tomcat远程代码执行漏洞CVE-2019-0232(573)
  10. 网上赌博平台维护审核提不了款怎么办?(535)
  11. React 与 React-Native 使用同一个 meteor 后台(529)
  12. Sublime Text3 最新版3207 安装及破解(458)
  13. Visual Studio 2019 正式发布(389)
  14. [翻译] Visual Studio 2019: 极速编码. 智能工作. 创造未来.(389)
  15. 刘强东身边的CXO还有谁“幸存”(373)
  16. 舍命生子产妇吴梦丈夫怒斥:没抢肺源不是精神分裂,网友断章取义(371)
  17. Confluence SSRF及远程代码执行漏洞处置手册(370)
  18. 阿里巴巴2018年纳税516亿元 同比增40%(370)
  19. 机器学习 ML.NET 发布 1.0 RC(369)
  20. K8s集群安装--最新版 Kubernetes 1.14.1(338)
  21. 雷军清华演讲实录:小米9年的创新、变革与未来(334)
  22. 小米手机卖不动了?(327)
  23. F#周报2019年第14期(317)
  24. 积分一样却选手下败将出战国际赛,《最强大脑》云队选手被坑了?(300)
  25. 《最强大脑》要垮?桑洁魏坤琳出轨细节被扒,戚薇才是神助攻(257)
  26. 华电教授孙玉兵被指与昔日同学共同学术造假,多所高校调查(251)
  27. F#周报2019年第15期(249)
  28. 日本明仁天皇退位,日本“平成”年代结束(246)
  29. linux系统安装cdcfordb2udb(241)
  30. Oracle甲骨文大规模裁员,你背离时代就会被淘汰(240)
  31. 他联系叙恐怖分子“卖军火”,称能搞到2000枚导弹,关键时刻中国警察出手(237)
  32. 针对django2.2报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: ill....(236)
  33. 魔兽世界:8.15搏击俱乐部坐骑获取流程 鳄鱼布鲁斯坐骑(236)
  34. 女友被曝插足许志安郑秀文婚姻 知情人透露马国明已下定决心分手(232)
  35. SQL简介及MySQL的安装目录详解(229)
  36. 视觉中国深夜道歉:全面配合监管部门彻底积极整改(229)
  37. 为什么国内汽车用沥青阻尼片,而欧洲主机厂却用树脂?(229)
  38. 谁是苏小明饭局爆粗偷拍者?知情人称另有其人(225)
  39. NodeJs之邮件(email)发送(223)
  40. 迪玛希好惨!昨晚《歌手》为声入人心男团帮帮唱,却再被指控侵权(223)
  41. 市值暴跌90%,世界零售巨头申请破产战胜了所有对手却输时代(221)
  42. 函数防抖,与函数节流(221)
  43. 机器学习基石笔记:01 The Learning Problem(218)
  44. 深度学习python的配置(Windows)(215)
  45. [深度应用]·实战掌握Dlib人脸识别开发教程(213)
  46. 许志安出轨视频系蓄谋偷拍?司机被曝收40万装红外摄像头(210)
  47. Google AI 系统 DeepMind 高中数学考试不及格(210)
  48. 干货!21部漫威电影观影顺序指南,在《复联4》之前赶紧补齐!(209)
  49. 赌命生子九个月后,吴梦离世:前半辈子任性了,我用生命买单(206)
  50. 威廉王子出轨凯特王妃闺蜜? 外媒称婚外情致兄弟反目(203)
  51. spring-cloud-sleuth+zipkin源码探究(203)
  52. WebGL three.js学习笔记 纹理贴图模拟太阳系运转(201)
  53. 新更新kb4493472导致无法正常开机(195)
  54. 杜敬谦死因疑曝光!或因他这一特殊的训练方式,泳迷高呼孙杨退役(191)
  55. AntDesign Form表单字段校验的三种方式(189)
  56. 韦杰落网,金诚集团终局(188)
  57. 华为推出方舟编译器 称可提升安卓系统效率(186)
  58. 山东庆云民企3000亩土地被贱卖 国企接盘拟转性(185)
  59. 《权力的游戏》龙妈有那么多爱她的人,为什么最终会选择琼恩雪诺(183)
  60. 张无忌为什么爱上她?陈钰琪版赵敏终于给答案了(181)
  61. “国防”靠美国? 韩国瑜=马英九2.0? 走着瞧(180)
  62. 直认与老公感情淡了!27岁TVB上位女星:我们不是好熟(180)
  63. Python破解Wifi密码思路(180)
  64. CUBA Studio 8.0 发布,企业级应用开发平台(179)
  65. Github 上 Star 最多的个人 Spring Boot 开源学习项目(178)
  66. 张丹峰出轨最新锤来了!毕滢的朋友圈简直刷新下限啊!(177)
  67. 拿着普通员工超300倍的工资裁员800人,这家游戏公司CEO引发员工不满|一周新闻(177)
  68. 币安称 4000 万美元比特币被盗(175)
  69. 使用 C 语言实现一个 HTTP GET 连接(175)
  70. 不要996!程序员创建955.WLB不加班公司名单,GitHub周榜第二(175)
  71. AntD框架的upload组件上传图片时遇到的一些坑(175)
  72. 《跃迁-成为高手的技术》之联机学习(174)
  73. Codejam Qualification Round 2019(174)
  74. Weblogic CVE-2019-2647等相关XXE漏洞分析(173)
  75. python爬虫重定向次数过多问题(172)
  76. simulink创建简单模型(172)
  77. 强大的jQGrid的傻瓜式使用方法。以及一些注意事项,备有相应的引入文件。(170)
  78. [NewLife.XCode]高级查询(168)
  79. Algolia使用教程 , 超详细傻子看都会(166)
  80. Delphi 开发微信公众平台 (二) 用户管理(165)
  81. 核心算法缺位,人工智能发展面临“卡脖子”窘境(165)
  82. 告诉你去越南芽庄必带回的好东西(163)
  83. 只需知道电话号码 即可监控任意一部手机,获取位置,太可怕(163)
  84. 范斯晶对祖母的称呼很意外,范志毅很心疼,缺少母爱的孩子不容易(162)
  85. 如何定位前端线上问题(如何排查前端生产问题)(162)
  86. 百度网盘下载神器 PanDownload v2.0.9(破解版、不限速)(160)
  87. 双双出轨!许志安劈腿马国明港姐女友,二人被拍16分钟激吻超20次(160)
  88. 数学家发现完美的乘法(160)
  89. 定义工作,解读自我——IT帮2019年2月线下活动回顾(160)
  90. 高管被警方带走背后:巧达科技操盘2亿人简历生意(159)
  91. 吹爆惠英红,《铁探》这位霸道总警司超带感!真乃港剧罕见大女主(157)
  92. vue生成图片验证码(156)
  93. 三国正史第一猛将:一人单挑数千人,不是吕布也不是关羽(155)
  94. 从0到1上线一个微信小程序(154)
  95. FreeSql 如何现实 Sqlite 跨库查询(154)
  96. 向佐的弟弟叫向佑,网友:那郭碧婷生的孩子叫什么?(153)
  97. [Node.js] 3、搭建hexo博客(153)
  98. spring-boot-2.0.3不一样系列之源码篇 - pageHelper分页,绝对有值得你看的地方(153)
  99. TensorFlow从1到2(十)带注意力机制的神经网络机器翻译(152)
  100. java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的(152)

  1. 函数优化实战
  2. numpy数组之存取文件
  3. 曾之乔眼眶泛红爆哭! 5万粉虐心看10秒 最后一刻笑了
  4. 自杀式选角
  5. 登陆Linux服务器时触发邮件提醒
  6. 风暴中的华为员工信首次公布:女朋友停止吵架,家人劝不要做逃兵
  7. 莫迪大胜,对中国意味着什么?
  8. 搞假材料欺骗中央,书记区长双双被免
  9. 小白入门AI教程:教你快速搭建大数据平台『Hadoop+Spark』
  10. MySQL 事务
  11. [Inside HotSpot] Serial垃圾回收器 (二) Minor GC
  12. 老婆举报医生老公“收药品回扣”:他出轨并要求离婚 官方已介入调查
  13. 实验吧简单的sql注入3
  14. 死磕 java同步系列之自己动手写一个锁Lock
  15. [NOI2006] 网络收费
  16. 线性基的小证明...
  17. 从语言设计的角度探究Java中hashCode()和equals()的关系
  18. C# 多线程小试牛刀
  19. Python基础:输入与输出(I/O)
  20. link-1-STL 标准模板库
  21. mysql--浅谈多表查询1
  22. 进击JavaScript核心 --- (1)基本数据类型
  23. 大数据技术之_24_电影推荐系统项目_07_工具环境搭建(具体实操)
  24. 前端限制显示的文本字数的几种方法——不换行与换行
  25. 【实验吧】该题不简单——writeup
  26. 反向传播算法
  27. =、==、===、equals()的区别
  28. GitHub 推出开发者赞助项目
  29. 剑指Offer的学习笔记(C#篇)-- 从上往下打印二叉树
  30. argparse 在深度学习中的应用
  31. 张云雷复出?西城区文旅局:德云社在辖区内演出未发现违法违规问题
  32. Maven安装与配置
  33. acWing 825. 排队购物
  34. ajax&&jquery
  35. 苏联攻击机的悲壮行动,明知德军战机拦截,仍在无护航状态下出击
  36. 华为的5G技术,源于这种数学方法
  37. 一站式自动化测试平台 http://www.Autotestplat.com
  38. RabbitMQ总结
  39. 第九组 通信3班 063 自反ACL
  40. 短线还有最后一跌?大V们表示:反弹近了!(5月23日)
  41. 第九组 通信3班 063 OSPFv2与OSPFv3综合实验
  42. C# IE选项 - 重置IE
  43. Spring_数据校验和自定义检验规则
  44. 谈谈Java的string为什么是不可变的
  45. OFFICE 365 A1 Plus账号注册
  46. 初学python—做一个数组的增删改查操作
  47. oc工程中oc、swift混编代码打包成静态framework踩坑笔记
  48. 阿里云推“智能秒停系统”:50秒内短信通知 再不怕吃罚单
  49. 今天购买了一个云服务器
  50. 神奇!乌鸦竟然会传达悲观和怀疑情绪 还会对同伴“冷嘲热讽”
  51. 数字IC设计入门必备——VIM自定义模板调用与VCS基本仿真操作示例
  52. 点击事件的坐标计算(client || offset) +(X || Width || Left) 各种排列组合别绕晕
  53. windows下dubbo-admin2.6.x之后版本的安装
  54. linux 之基本命令学习总结
  55. 传祺难续“传奇”?销量暴跌超4成 加价卖车被“断裂门”尽毁
  56. 香港豪门后宫持续曝光:他用选美比赛“选妃”,与几万女星交往
  57. 小窥React360——用React创建360全景VR体验
  58. Spring Boot 2 快速教程:WebFlux 集成 Mongodb(四)
  59. .Net Core下使用RabbitMQ比较完备的两种方案(虽然代码有点惨淡,不过我会完善)
  60. “80后”女博士已任团中央书记处书记
  61. 杨元庆:现在是联想的最好时刻 我们四大战役全部打了胜仗
  62. Java开发环境的搭建(JDK和Eclipse的安装)
  63. oracle学习笔记(十四) 数据库对象 索引 视图 序列 同义词
  64. 机构风向标:外资出逃超500亿 美的集团等白马股表现欠佳
  65. 跟踪记录ABAP对外部系统的RFC通信
  66. c++11多线程详解(一)
  67. 小蓝杯,跌破发行价了
  68. [NewLife.XCode]百亿级性能
  69. 33岁何洁商场走穴被曝光,路人镜头下的她与精修图差别好大
  70. 途牛第一季度净亏损2240万美元 同比亏损幅度扩大
  71. 00 | Two Sum
  72. 智能威胁分析之图数据构建
  73. 快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示
  74. Neo4j 第六篇:Cypher语法
  75. Java微信公众平台开发(三)--接收消息的分类及实体的创建
  76. Java8 中的 Optional
  77. 如何显示超大图像(3)
  78. 贵州检察机关依法对袁仁国决定逮捕
  79. 有关xerospolit运行报错问题的有效解决方案
  80. ADO学途 one day
  81. Linux 中 ip netns 命令
  82. Python爬虫之设置selenium webdriver等待
  83. BSOJ1040 -- 【练习题目】美元DOLLARS
  84. 外媒:稀土是中国手中的一张王牌
  85. sql server添加sa用户和密码
  86. 深入理解JVM的类加载
  87. querySelector和getElementById之间的区别
  88. 简说设计模式——观察者模式
  89. 扰动函数和拉链法模拟HashMap的存储结构
  90. 东芝中国:“上海东芝公司”不存在 未停止与华为的合作
  91. 彭于晏马思纯主演张爱玲这部小说,却被说更适合演《骆驼祥子》?
  92. 停止向华为供货?东芝辟谣回应
  93. 云米第一季度净利润5310万元 同比增长68%
  94. 贪吃的古蛙,古生物学家发现亿年前两栖动物之间战争
  95. APICloud发布低代码开发平台 效率提升30%至60%
  96. Golang 读写锁RWMutex 互斥锁Mutex 源码详解
  97. shell初级-----数据呈现方式
  98. 白玉兰入围名单公布!《知否》《都挺好》上榜,还有这部豆瓣3分剧
  99. 深网 | 京东618接入快手、抖音 实现“即看即买”
  100. 解决 APP启动白屏黑屏问题