Ошибка AWS Cors - Node.js

В настоящее время я испытываю проблему при запросе изображений, хранящихся на AWS S3 (простое хранилище) с заголовком CORS. Я настроил конфигурацию CORS на консоли AWS - и настройка выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Однако ответ, который я получаю при запросе этих изображений, которые я сохранил, немного повсеместно и довольно прерывистый. Иногда изображение возвращается с требуемыми заголовками, а иногда и нет. Я действительно не знаю, почему это происходит. Также кажется, что эффект ухудшается, когда я пытаюсь сделать несколько запросов для изображения с заголовком Access-Control-Allow-Origin, установленным как * на странице (например, если мне нужно 10 изображений для получения всех с заголовками с перекрестным контуром).

Вот те заголовки, которые мне нужны:

Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3000

Я действительно не уверен, что я делаю неправильно. Я убедился, что каждый тег изображения имеет атрибут crossOrigin = "анонимный", добавленный к нему, но опять же, не повезло.

Причина, по которой мне нужно, чтобы эти изображения работали с перекрестным происхождением, заключается в том, что я установил плагин angular, который позволяет пользователю обрезать изображения и сохранять обрезанные версии изображений в виде строк base64. Тем не менее, я получаю следующую ошибку при попытке восстановить их.

введите описание изображения здесь

Это заголовки для изображения, которое возвращается правильно:

Request URL:https://trajansmarket.s3.amazonaws.com/be5bbda0-b04a-11e5-81d3-dd7ff3efeebc.jpg
Request Method:GET
Status Code:304 Not Modified
Remote Address:54.231.252.131:443

Response Headers
view source
Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3000
Cache-Control:public, max-age=31536000
Date:Tue, 12 Jan 2016 21:13:03 GMT
ETag:"77bdbe9b517acc8cba86024c592bce3f"
Last-Modified:Fri, 01 Jan 2016 05:46:21 GMT
Server:AmazonS3
Vary:Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2:F3OQpOHsAqySk9LNwwoJXVATVIByr4Gtvz953ZoL7DdB/dtE9nYwo99R59Rj6RzZc3dcHyk6wWY=
x-amz-request-id:CD220FF1F6EE6CA9

Request Headers
view source
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6,ms;q=0.4
Connection:keep-alive
Host:trajansmarket.s3.amazonaws.com
If-None-Match:"77bdbe9b517acc8cba86024c592bce3f"
Origin:http://91.121.220.161:3000
Referer:http://91.121.220.161:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36

И здесь один без заголовков:

Request URL:https://trajansmarket.s3.amazonaws.com/c0671e00-b04a-11e5-81d3-
dd7ff3efeebc.jpg
Request Method:GET
Status Code:200 OK (from cache)
Remote Address:54.231.252.135:443

Response Headers
Accept-Ranges:bytes
Cache-Control:public, max-age=31536000
Content-Length:142102
Content-Type:application/octet-stream
Date:Tue, 12 Jan 2016 00:35:36 GMT
ETag:"beb93f56e3a2a65b983addd8af35c26c"
Last-Modified:Fri, 01 Jan 2016 05:46:25 GMT
Server:AmazonS3
x-amz-id-2:5XvaOd8bxMr5zwK317DfDMbk2+kzu3Zd7rsf2xl0hxwI40Oc4KDnQpgzD3sgtCRm9SXGqa93Mh0=
x-amz-request-id:FD3EB1978C38013B

Request Headers
Provisional headers are shown
Accept:image/webp,image/*,*/*;q=0.8
Origin:http://91.121.220.161:3000
Referer:http://91.121.220.161:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id:498F45FE-5D49-4AE0-AF58-F81B9AFD48AF

Мне просто интересно, есть ли у кого-нибудь представление о том, почему это произойдет. Любая помощь будет принята с благодарностью.

Ответ 1

Это было очень неприятно, и я еще не решил причину, по которой AWS S3 периодически возвращал заголовки, которые мне нужны для CORS.

С тех пор я думал об обходном пути, который заключается в "загрузке" и хранении изображений, которые мне нужны с amazon, в локальной папке - разрешить пользователю "обрезать" изображение и сохранить его до удаления этих изображений с локального папка.

Чтобы передать файлы изображений в локальную папку, я использовал метод fs.createWriteStream для метода .getObject из s3. Пример этого можно найти по адресу: введите ссылку здесь

Это избавило меня от необходимости запрашивать изображения с заголовками CORS, поскольку, когда они хранятся локально, заголовки больше не требуются. Затем я могу сохранить base64, который генерируется моей директивой обрезки, и легко хранить это на amazon S3.

Если пользователь перемещается, прежде чем обрезать локальные изображения, я удаляю их из локальной папки, чтобы он не засорился.

Надеюсь, это поможет некоторым тем, у кого проблемы с заголовками CORS - хотя это всего лишь обходной путь.

Ответ 2

Хорошо, я видел эту проблему в нескольких разных формах: один из них - это то, где вы обслуживаете страницу на S3, которая обращается к серверу nodejs либо в EC2, либо в Elastic Beanstalk.

В одном случае браузером я пользовался IE10, который забрасывал ошибки, потому что браузеру необходимо было установить параметры предварительной проверки.

В других случаях я использовал Restify in Elastic Beanstalk и Angular в S3. Я добавил пакет промежуточного ПО Restify-cors к запросу:

var corsMiddleWare = require('restify-cors-middleware'); //npm install this package
var cors = corsMiddleWare ({
    allowHeaders:['Authorization', 'API-Token', 'API-Token-Expiry']
 });
server.pre(cors.preflight);
server.use(cors.actual);
//rest of server definition

Казалось, это сработало. В случае экспресс есть пакет node express-cors:

var cors = require('cors');
app.use(cors());

В любом случае ключ состоит в том, что все запросы должны иметь правильные заголовки, поэтому мы добавляем их в промежуточное программное обеспечение. (Приложение/server.use) Как я могу поддерживать cors при использовании restify

Используете ли вы ваниль node? В этом случае вам нужно добавить заголовки для каждого запроса, который вы делаете на s3.

Ответ 3

Это определенно проблема с тем, что это был кешированный ответ для меня. Кажется, он потерял некоторые из заголовков в кеше. Я смог заставить его работать в 100% случаев, добавив случайный параметр времени в имя изображения, как в примере ниже.

img = new Image();
img.src = "https://s3.amazonaws.com/bucket/img.png?t=" + (new Date().getTime() / 1000);    
img.crossOrigin = "Anonymous";