مرحله 5: اضافه کردن تصاویر از وب

در این مرحله یاد خواهید گرفت:

  • نحوه بارگیری منابع از خارج از برنامه و افزودن آنها به DOM از طریق XHR و ObjectURL.

زمان تخمینی برای تکمیل این مرحله: 20 دقیقه.
برای پیش نمایش آنچه در این مرحله تکمیل می کنید، به پایین این صفحه بروید ↓ .

چگونه CSP بر استفاده از منابع خارجی تأثیر می گذارد

پلتفرم Chrome Apps برنامه شما را مجبور می‌کند که کاملاً با خط‌مشی‌های امنیت محتوا (CSP) مطابقت داشته باشد. نمی‌توانید مستقیماً منابع DOM مانند تصاویر، فونت‌ها و CSS را از خارج از بسته برنامه Chrome خود بارگیری کنید.

اگر می خواهید یک تصویر خارجی در برنامه خود نشان دهید، باید آن را از طریق XMLHttpRequest درخواست کنید، آن را به یک Blob تبدیل کنید و یک ObjectURL ایجاد کنید. این ObjectURL می توان به DOM اضافه کرد زیرا به یک آیتم در حافظه در زمینه برنامه اشاره دارد.

نمایش تصاویر کوچک برای موارد انجام کار

بیایید برنامه خود را تغییر دهیم تا به دنبال URL های تصویر در یک مورد انجام شود. اگر نشانی اینترنتی شبیه یک تصویر است (برای مثال، به .png.، jpg.، .svg یا .gif ختم می‌شود)، فرآیند ذکر شده در بالا را برای نشان دادن یک تصویر کوچک در کنار URL اعمال کنید.

به روز رسانی مجوزها

در یک برنامه Chrome، تا زمانی که دامنه آن را در مانیفست مشخص کرده باشید، می‌توانید با هر URL با XMLHttpRequest تماس برقرار کنید. از آنجایی که از قبل نمی‌دانید کاربر چه URL تصویری را تایپ می‌کند، اجازه درخواست کنید تا به "<all_urls>" درخواست کنید.

در manifest.json ، درخواست کنید " اجازه:

"permissions": ["storage", "alarms", "notifications",
                "webview", "<all_urls>"],

ObjectURL ها را ایجاد و پاک کنید

در controller.js ، یک متد _createObjectURL() برای ایجاد ObjectURL از Blob اضافه کنید:

Controller.prototype._createObjectURL = function(blob) {
  var objURL = URL.createObjectURL(blob);
  this.objectURLs = this.objectURLs || [];
  this.objectURLs.push(objURL);
  return objURL;
};

ObjectURL ها حافظه را نگه می دارند، بنابراین وقتی دیگر به ObjectURL نیاز ندارید، باید آنها را باطل کنید. این متد _clearObjectURL() را به controller.js اضافه کنید تا به آن رسیدگی کنید:

Controller.prototype._clearObjectURL = function() {
  if (this.objectURLs) {
    this.objectURLs.forEach(function(objURL) {
      URL.revokeObjectURL(objURL);
    });
    this.objectURLs = null;
  }
};

درخواست XHR کنید

یک متد _requestRemoteImageAndAppend() اضافه کنید تا یک XMLHttpRequest در URL تصویر داده شده اجرا شود:

Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imageUrl);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var img = document.createElement('img');
    img.setAttribute('data-src', imageUrl);
    img.className = 'icon';
    var objURL = this._createObjectURL(xhr.response);
    img.setAttribute('src', objURL);
    element.appendChild(img);
  }.bind(this);
  xhr.send();
};

در بارگذاری XHR، این روش یک ObjectURL از پاسخ XHR ایجاد می کند و یک عنصر <img> را با این ObjectURL به DOM اضافه می کند.

URL های تصویر را در موارد انجام کار تجزیه کنید

اکنون یک متد _parseForImageURLs() اضافه کنید که تمام پیوندهایی را که هنوز پردازش نشده اند پیدا کرده و آنها را برای تصاویر بررسی می کند. برای هر URL که شبیه یک تصویر است، _requestRemoteImageAndAppend() را اجرا کنید:

Controller.prototype._parseForImageURLs = function () {
  // remove old blobs to avoid memory leak:
  this._clearObjectURL();
  var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
  var re = /\.(png|jpg|jpeg|svg|gif)$/;
  for (var i = 0; i<links.length; i++) {
    var url = links[i].getAttribute('data-src');
    if (re.test(url)) {
      links[i].classList.add('thumbnail');
      this._requestRemoteImageAndAppend(url, links[i]);
    }
  }
};

ریز عکسها را در لیست کارهای انجام دهید

اکنون _parseForImageURLs() را از showAll() , showActive() و showCompleted() فراخوانی کنید:

/**
 * An event to fire on load. Will get all items and display them in the
 * todo-list
 */
Controller.prototype.showAll = function () {
  this.model.read(function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all active tasks
 */
Controller.prototype.showActive = function () {
  this.model.read({ completed: 0 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all completed tasks
 */
Controller.prototype.showCompleted = function () {
  this.model.read({ completed: 1 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

همین کار را برای editItem() انجام دهید:

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
    if (value.length && !discarding) {
      ...
      label.innerHTML = this._parseForURLs(value);
      this._parseForImageURLs();
    } else if (value.length === 0) {
  ...
}

ابعاد تصویر نمایش داده شده را محدود کنید

در نهایت، در _bower components/todomvc-common/base.css ، یک قانون CSS برای محدود کردن اندازه تصویر اضافه کنید:

.thumbnail img[data-src] {
  max-width: 100px;
  max-height: 28px;
}

برنامه Todo تمام شده خود را راه اندازی کنید

شما مرحله 5 را تمام کردید! برنامه خود را مجدداً بارگیری کنید و یک مورد todo با URL به تصویری که به صورت آنلاین میزبانی شده است اضافه کنید. برخی از نشانی‌های اینترنتی که می‌توانید استفاده کنید: http://goo.gl/nqHMF#.jpg یا http://goo.gl/HPBGR#.png .

برای اطلاعات بیشتر

برای اطلاعات دقیق تر در مورد برخی از API های معرفی شده در این مرحله، به آدرس زیر مراجعه کنید:

برای ادامه به مرحله بعدی آماده هستید؟ برو به مرحله 6 - صادرات todos به سیستم فایل »

،

در این مرحله یاد خواهید گرفت:

  • نحوه بارگیری منابع از خارج از برنامه و افزودن آنها به DOM از طریق XHR و ObjectURL.

زمان تخمینی برای تکمیل این مرحله: 20 دقیقه.
برای پیش نمایش آنچه در این مرحله تکمیل می کنید، به پایین این صفحه بروید ↓ .

چگونه CSP بر استفاده از منابع خارجی تأثیر می گذارد

پلتفرم Chrome Apps برنامه شما را مجبور می‌کند که کاملاً با خط‌مشی‌های امنیت محتوا (CSP) مطابقت داشته باشد. نمی‌توانید مستقیماً منابع DOM مانند تصاویر، فونت‌ها و CSS را از خارج از بسته برنامه Chrome خود بارگیری کنید.

اگر می خواهید یک تصویر خارجی در برنامه خود نشان دهید، باید آن را از طریق XMLHttpRequest درخواست کنید، آن را به یک Blob تبدیل کنید و یک ObjectURL ایجاد کنید. این ObjectURL می توان به DOM اضافه کرد زیرا به یک آیتم در حافظه در زمینه برنامه اشاره دارد.

نمایش تصاویر کوچک برای موارد انجام کار

بیایید برنامه خود را تغییر دهیم تا به دنبال URL های تصویر در یک مورد انجام شود. اگر نشانی اینترنتی شبیه یک تصویر است (برای مثال، به .png.، jpg.، .svg یا .gif ختم می‌شود)، فرآیند ذکر شده در بالا را برای نشان دادن یک تصویر کوچک در کنار URL اعمال کنید.

به روز رسانی مجوزها

در یک برنامه Chrome، تا زمانی که دامنه آن را در مانیفست مشخص کرده باشید، می‌توانید با هر URL با XMLHttpRequest تماس برقرار کنید. از آنجایی که از قبل نمی‌دانید کاربر چه URL تصویری را تایپ می‌کند، اجازه درخواست کنید تا به "<all_urls>" درخواست کنید.

در manifest.json ، درخواست کنید " اجازه:

"permissions": ["storage", "alarms", "notifications",
                "webview", "<all_urls>"],

ObjectURL ها را ایجاد و پاک کنید

در controller.js ، یک متد _createObjectURL() برای ایجاد ObjectURL از Blob اضافه کنید:

Controller.prototype._createObjectURL = function(blob) {
  var objURL = URL.createObjectURL(blob);
  this.objectURLs = this.objectURLs || [];
  this.objectURLs.push(objURL);
  return objURL;
};

ObjectURL ها حافظه را نگه می دارند، بنابراین وقتی دیگر به ObjectURL نیاز ندارید، باید آنها را باطل کنید. این متد _clearObjectURL() را به controller.js اضافه کنید تا به آن رسیدگی کنید:

Controller.prototype._clearObjectURL = function() {
  if (this.objectURLs) {
    this.objectURLs.forEach(function(objURL) {
      URL.revokeObjectURL(objURL);
    });
    this.objectURLs = null;
  }
};

درخواست XHR کنید

یک متد _requestRemoteImageAndAppend() اضافه کنید تا یک XMLHttpRequest در URL تصویر داده شده اجرا شود:

Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imageUrl);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var img = document.createElement('img');
    img.setAttribute('data-src', imageUrl);
    img.className = 'icon';
    var objURL = this._createObjectURL(xhr.response);
    img.setAttribute('src', objURL);
    element.appendChild(img);
  }.bind(this);
  xhr.send();
};

در بارگذاری XHR، این روش یک ObjectURL از پاسخ XHR ایجاد می کند و یک عنصر <img> را با این ObjectURL به DOM اضافه می کند.

URL های تصویر را در موارد انجام کار تجزیه کنید

اکنون یک متد _parseForImageURLs() اضافه کنید که تمام پیوندهایی را که هنوز پردازش نشده اند پیدا کرده و آنها را برای تصاویر بررسی می کند. برای هر URL که شبیه یک تصویر است، _requestRemoteImageAndAppend() را اجرا کنید:

Controller.prototype._parseForImageURLs = function () {
  // remove old blobs to avoid memory leak:
  this._clearObjectURL();
  var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
  var re = /\.(png|jpg|jpeg|svg|gif)$/;
  for (var i = 0; i<links.length; i++) {
    var url = links[i].getAttribute('data-src');
    if (re.test(url)) {
      links[i].classList.add('thumbnail');
      this._requestRemoteImageAndAppend(url, links[i]);
    }
  }
};

ریز عکسها را در لیست کارهای انجام دهید

اکنون _parseForImageURLs() را از showAll() , showActive() و showCompleted() فراخوانی کنید:

/**
 * An event to fire on load. Will get all items and display them in the
 * todo-list
 */
Controller.prototype.showAll = function () {
  this.model.read(function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all active tasks
 */
Controller.prototype.showActive = function () {
  this.model.read({ completed: 0 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all completed tasks
 */
Controller.prototype.showCompleted = function () {
  this.model.read({ completed: 1 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

همین کار را برای editItem() انجام دهید:

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
    if (value.length && !discarding) {
      ...
      label.innerHTML = this._parseForURLs(value);
      this._parseForImageURLs();
    } else if (value.length === 0) {
  ...
}

ابعاد تصویر نمایش داده شده را محدود کنید

در نهایت، در _bower components/todomvc-common/base.css ، یک قانون CSS برای محدود کردن اندازه تصویر اضافه کنید:

.thumbnail img[data-src] {
  max-width: 100px;
  max-height: 28px;
}

برنامه Todo تمام شده خود را راه اندازی کنید

شما مرحله 5 را تمام کردید! برنامه خود را مجدداً بارگیری کنید و یک مورد todo با URL به تصویری که به صورت آنلاین میزبانی شده است اضافه کنید. برخی از نشانی‌های اینترنتی که می‌توانید استفاده کنید: http://goo.gl/nqHMF#.jpg یا http://goo.gl/HPBGR#.png .

برای اطلاعات بیشتر

برای اطلاعات دقیق تر در مورد برخی از API های معرفی شده در این مرحله، به آدرس زیر مراجعه کنید:

برای ادامه به مرحله بعدی آماده هستید؟ برو به مرحله 6 - صادرات todos به سیستم فایل »