vikkyshostak
@vikkyshostak
< This head full of dreams.

Что не так с CORS при использовании Fetch API + Babel + Webpack?

Доброго времени года!

Перевожу свой скромный скрипт соц. кнопок goodshare.js на ES6. На локалхосте (macOS 10.11.6, Safari 10+, FF, Chrome) всё отрабатывается – данные по кол-ву расшариваний в социалках получаю и вывожу без проблем. Но стоит перенести на хостинг – всё в варнингах:

[Error] XMLHttpRequest cannot load ... 
Origin http://goodshare.ru is not allowed by Access-Control-Allow-Origin.

Вот живой пример: goodshare.ru/examples/example-1.html

Конфиг такой:
– для GET запроса к соц. сети использую Fetch API (mode: cors);
– Babel;
– собираю всё через Webpack.

Вот файл для сборки (где все import-ы): https://github.com/koddr/goodshare.js/blob/master/...
Вот package.json: https://github.com/koddr/goodshare.js/blob/master/...

Для примера, вот метод получения счётчика шаринга из провайдера Вконтакте:

// ./src/providers/Vkontakte.js

export class Vkontakte {

  // Конструктор
  constructor(url = document.location.href) {
    this.url = encodeURIComponent(url);
  }

  // Метод для получения счётчика ВК
  getCounter() {
    let count_url = 'https://vk.com/share.php?act=count&index=1&url=' + this.url;
    
    fetch(count_url, {method: 'GET', mode: 'cors'})
      .then(this.checkStatus)
      .then((response) => {
        return response.text();
      })
      .then((counter) => {
        document.body
          .querySelectorAll("[data-counter=vkontakte]")
          .forEach(function (item) {
            return item.innerHTML = counter.match(/^VK\.Share\.count\(\d, (\d+)\);$/)[1] / 1;
          });
      })
      .catch((error) => {
        console.log('Request failed!', error);
      });
  };
}

// ./src/index.js

import 'whatwg-fetch'; // Полифилл для разных браузеров

import { Vkontakte } from './providers/Vkontakte'; // Подключаю провайдер Вконтакта

new Vkontakte().getCounter(); // Даёт ошибку CORS, которую описал выше.

Что не так? Почему, даже задав mode: cors, не уходит кроссдоменный запрос?

Помогите, пожалуйста, разобраться! Буду раз любому pull-request :D
  • Вопрос задан
  • 2246 просмотров
Решения вопроса 1
@Sayonji
vk.com/share.php использует подобие jsonp. Вот пример:
window.VK = {Share:{}}

class Vkontakte {
  constructor(url = document.location.href) {
    this.url = encodeURIComponent(url);
  }
  getCounter() {
    let count_url = 'https://vk.com/share.php?act=count&index=1&url=' + this.url;
    window.VK.Share.count = (_, counter) => {
        console.log(counter)
        script.parentNode.removeChild(script)
    }
    let script = document.createElement('script')
    script.src = count_url
    document.body.appendChild(script)
  };
}

new Vkontakte().getCounter();

Через ajax-запрос vk данные не отдаёт, так что fetch тут не поможет.

Tumblr же использует настоящий jsonp. Скачайте библиотеку или делайте вручную, например так:
class Tumblr {
  constructor(url = document.location.href) {
    this.url = encodeURIComponent(url);
  }
  getCounter() {
    let callback = ('cb_' + Math.random()).replace('.', '')
    let count_url = 'https://api.tumblr.com/v2/share/stats?url=' + this.url +
      '&callback=' + callback;
    window[callback] = function(counter) {
        console.log(counter.response.note_count)
        script.parentNode.removeChild(script)
    }
    let script = document.createElement('script')
    script.src = count_url
    document.body.appendChild(script)
  };
}

new Tumblr().getCounter();
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы