【问题标题】:CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resourceCORS 策略:请求的资源上不存在“Access-Control-Allow-Origin”标头
【发布时间】:2017-09-10 11:50:13
【问题描述】:

我在 Heroku 上托管的 AngularJS 应用程序不断收到以下错误:

在以下位置访问图像 'https://d15790c7fypqrz.cloudfront.net/attachments/product_template_pictures/images/000/490/265/grid/832816_122.png' 来自 'http://.herokuapp.com' 的来源已被阻止 CORS 策略:没有“Access-Control-Allow-Origin”标头出现在 请求的资源。起源 'http://.herokuapp.com' 因此不是 允许访问。

我该如何解决?这是进行base64转换的代码:

function createBase64Property(product, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'Anonymous';
  img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(product, dataURL);
  };
  img.src = product.imageUrl;
  if (img.complete || img.complete === undefined) {
    img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
    img.src = product.imageUrl;
  }
}

我的web.js配置如下:

var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var cors = require('cors')

var app = express();

app.use(morgan('dev'));
app.use(gzippo.staticGzip(__dirname));
app.use(cors({credentials: true, origin: true}));
app.all('*', function(req, res, next) {
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Headers", "X-Requested-With");
   res.header('Access-Control-Allow-Headers', 'Content-Type');
   next();
});
app.listen(process.env.PORT || 5000);

【问题讨论】:

  • 它的d15790c7fypqrz.cloudfront.net 需要允许跨域请求,而不是你自己的服务器。但看起来您发布的代码与该错误无关。
  • @robertklep 你知道有什么免费的地方可以上传允许跨域请求的图片吗?
  • 为什么图片需要跨域请求支持?你不能用<img src="https://d15790c7fypqrz.cloudfront.net/...">吗?
  • 我正在将图像转换为 base64 格式,然后将其与上传的图像进行比较。
  • 嗯,好吧,在这种情况下,我猜你会需要它。恐怕我不知道这样的地方:(

标签: angularjs node.js heroku


【解决方案1】:

好的,在这种情况下有一种绕过 CORS 的棘手方法。 如果您的 Angular 代码部署在节点服务器上,您可以代理您的图像 URL。您定义一个由节点处理的自定义路由,该路由将是本地的。

使用 grunt

您需要添加grunt-connect-proxy

https://github.com/drewzboto/grunt-connect-proxy

将其添加到您的 grunt 配置后,您必须编写代理中间件:

connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect().use(
                '/app/styles',
                connect.static('./app/styles')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      },
      proxies: [
            {
                context: '/outsides-images',
                host: 'd15790c7fypqrz.cloudfront.net/',
                https: true,
            }
        ]
    },

使用 gulp

我将向您展示一个使用 gulp 设置服务器的示例(我知道这不是一个完美的解决方案,但您可以看到模式):

import proxy from 'http-proxy-middleware';
import gulp-connect from 'gulp-connect';

const imagesServiceProxy = proxy('/outsides-images', {
  target: 'https://d15790c7fypqrz.cloudfront.net/',
  changeOrigin: true,
  logLevel: 'debug',
});

gulp.task('serve', () => {
  connect.server({
    port: 3000,
    root: [ './dest' ],
    livereload: false,
    middleware: (connect, opt) => {
      return [
        imagesServiceProxy,
        historyApiFallback(),
      ];
    },
  });
});

这个 sn-p 在 ES6 中,我用gulp-connect 设置服务器。

现在,在您的 AngularJS/HTML 代码中,当您获取图像时,使用代理 URL,类似这样:

/outside-images/attachments/product_template_pictures/images/000/490/265/grid/832816_122.png

我不知道你是如何设置服务器的,但我希望这个答案能给你一个关于绕过 CORS 的提示。

【讨论】:

  • 哈,是的,有点棘手:) 在回答正确的问题之前,我需要有关您的设置的更多信息。 - 在什么运行你的 AngularJS 代码? - 你使用快递或类似的东西吗? - 你是否使用过这些:gulp、grunt、webpack 等...?
  • 我有一个 gruntfile... 已在此处发布内容:pastebin.com/jQ4Swfvy。该应用程序按照此处的说明在 heroku 上设置:sitepoint.com/deploying-yeomanangular-app-heroku
  • 所有数据都是从 json 文件中加载的。在这里发布了一个例子:pastebin.com/mtfEqBKu.
  • 谢谢!我不再使用 grunt 了,但无论如何我已经编辑了答案。您可能需要对其进行调整。
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 2021-09-29
  • 2021-12-27
  • 1970-01-01
  • 2014-07-06
  • 2017-04-11
相关资源
最近更新 更多