HTML5 Canvas getImageData и одинаковая исходная политика
У меня есть сайт, запущенный на pixie.strd6.com и изображения, размещенные через Amazon S3 с CNAME для images.pixie.strd6.com.
Я хотел бы иметь возможность рисовать эти изображения на холсте HTML5 и вызывать метод getImageData, но он бросает Error: SECURITY_ERR: DOM Exception 18
Я попытался установить window.domain = "pixie.strd6.com"
, но это не имеет никакого эффекта.
Кроме того, $.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)})
также генерирует ошибку: XMLHttpRequest cannot load http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982. Origin http://pixie.strd6.com is not allowed by Access-Control-Allow-Origin.
В идеале холст HTML5 не будет блокировать вызов getImageData
из поддоменов. Я изучил настройку заголовка Access-Control-Allow-Origin в S3, но не удалось.
Приветствуется любая помощь или обходные пути.
Ответы
Ответ 1
Недавно Amazon объявила о поддержке CORS
Мы рады объявить о поддержке совместного использования ресурсов Cross-Origin (CORS) в Amazon S3. Теперь вы можете легко создавать веб-приложения, которые используют JavaScript и HTML5, чтобы взаимодействовать с ресурсами в Amazon S3, позволяя вам выполнять перетаскивание HTML5 на Amazon S3, показывать ход загрузки или обновлять контент. До сих пор вам нужно было запустить собственный прокси-сервер между вашим веб-приложением и Amazon S3 для поддержки этих возможностей.
Как включить CORS
Чтобы настроить ведро для разрешения запросов с кросс-началом, вы создаете конфигурацию CORS, документ XML с правилами, которые идентифицируют исходные данные, которые вы разрешите получать доступ к вашему ведру, операции (методы HTTP) будут поддерживать для каждого источника, и другую информацию, относящуюся к конкретной операции. Вы можете добавить до 100 правил. Вы добавляете XML-документ в качестве подресурса cors в ведро.
Ответ 2
Одним из возможных решений является использование nginx для работы в качестве прокси. Вот как настроить URL-адреса для http://pixie.strd6.com/s3/ для перехода на S3, но браузер все еще может поверить, что это непересекающийся домен.
location /s3/ {
proxy_pass http://images.pixie.strd6.com/;
}
Ответ 3
Если вы используете PHP, вы можете сделать что-то вроде:
function fileExists($path){
return (@fopen($path,"r")==true);
}
$ext = explode('.','https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg');
if(fileExists('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg')){
$contents = file_get_contents('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg');
header('Content-type: image/'.end($ext));
echo $contents;
}
И получить доступ к изображению с помощью этого php файла, например, если файл называется generateImage.php, вы можете сделать <img src="http://GENERATEPHPLOCATION/generateImage.php"/>
, а внешний URL-адрес изображения может быть параметром get для файла
Ответ 4
Недавно я наткнулся на $.getImageData
, Макс Новакович. На странице есть несколько аккуратных демонстраций извлечения и работы с фотографиями Flickr, а также некоторые примеры кода.
Он позволяет вам получить изображение в JavaScript-манипулируемой форме с произвольного сайта. Он работает, добавив script на страницу. Затем script запрашивает изображение с сервера Google App Engine. Сервер извлекает запрошенное изображение и передает его преобразование в base64 в script. Когда script получает base64, он передает данные в обратный вызов, который затем может нарисовать его на холст и начать с ним общаться.
Ответ 5
В прошлом Amazon S3 не позволял вам изменять или добавлять заголовки HTTP-заголовков access-control-allow-source и access-control-allow-credentials, поэтому было бы лучше переключиться на другую службу, например, Rackspace Cloud Файлы или какая-либо другая служба, которая делает.
Добавьте или измените заголовки HTTP следующим образом:
access-control-allow-origin: [your site]
access-control-allow-credentials: true
Подробнее см. http://www.w3.org/TR/cors/#use-cases.
Использование службы, которая позволяет изменять заголовки HTTP, полностью решает ту же проблему происхождения.
Ответ 6
Для людей, которые не используют S3, можно попытаться создать прокси-сервер изображения, который кодирует файл изображения и переносит его в объект JSON.
Затем вы можете использовать JSONP, который поддерживает кросс-домен, чтобы получить объект JSON и назначить данные изображения img.src.
Я написал пример кода прокси-сервера изображения с Google App Engine.
https://github.com/flyakite/gae-image-proxy
Объект JSON возвращается в формате, подобном этому
{
'height': 50,
'width' : 50,
'data' : 'data:image/jpeg;base64,QWRarjgk4546asd...QWAsdf'
}
"Данные" - это данные изображения в формате base64. Присвойте его изображению.
img.src = result.data;
Теперь изображение становится "чистым" для вашего холста.
Ответ 7
Чтобы отредактировать права на ведро S3:
1) Войдите в консоль управления AWS и откройте консоль Amazon S3 на https://console.aws.amazon.com/s3/
2) В списке "Ковши" откройте ведро, свойства которого вы хотите просмотреть, и нажмите "добавить конфигурацию CORS"
![amazon-screen-shot]()
3) Напишите правила, которые вы хотите добавить между тегами <CORSConfiguration>
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Подробнее о правилах вы можете узнать по адресу http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
4) Укажите crossorigin = 'anonymous' на изображении, которое вы будете использовать в своем холсте
Ответ 8
Это поведение пошагово. По спецификации HTML5, как только вы нарисуете крестообразное изображение на холст, он грязный, и вы больше не можете читать пиксели. Сравнение совпадений сравнивает схему, полностью квалифицированный хост и в браузерах, отличных от IE, порт.
Ответ 9
Просто столкнулся с той же проблемой. Я узнал о CORS, которые могут быть полезны.
http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#14
Это не сработало для меня, так как я пытаюсь манипулировать изображением Flickr. Итак, я все еще ищу решение.