0

I am trying to use a custom webfont to style a Stripe CardElement component. I have configured Stripe correctly to load the font, but it is blocked by CORS.

Access to font at 'https://...com/webfonts/stripe/L10-Regular.woff2' from origin 'https://js.stripe.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

(I'm using ...com in place of my live domain because the site is not yet ready to be public.)

In Node/Express, I have the following configuration:

app.use('/webfonts/stripe(/*)?', cors({
  origin: 'https://js.stripe.com',
  methods: ['GET', 'HEAD'],
  allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept']
}))

In the webfonts/stripe directory there is a l10-web.css file which I am passing to Stripe, here are its contents:

@font-face {
  font-family: "L10-Web";
  src: url("https://...com/webfonts/stripe/L10-Regular.woff2") format("woff2"),
       url("https://...com/webfonts/stripe/L10-Regular.woff") format("woff");
  font-style: normal;
  font-weight: 400;
}

And the two woff/2 files referenced in the CSS file.

I also tried setting each route explicitly (e.g. app.use('/webfonts/stripe/L10-Regular.woff', …)) but that didn't work either.

Is there something obvious I'm missing here? I don't understand why it says I'm missing the Access-Control-Allow-Origin header when I have it set in Express. I have set CORS on other routes just fine. Is it something to do with files?

(I have googled and googled and googled btw but to no avail)

David Yeiser
  • 1,438
  • 5
  • 22
  • 33
  • Is your Express server responsible for serving up the data from `https://...com` or `https://js.stripe.com`? – Quentin Nov 04 '20 at 14:53
  • Try to set res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN."). – MikiBelavista Nov 04 '20 at 14:58
  • @Quentin `https://...com` – David Yeiser Nov 04 '20 at 15:04
  • @MikiBelavista I did have that also at one point, but I need the fonts to be accessed from stripe.com, not my domain — or are you saying setting the origin for my domain as well has something to do with it? – David Yeiser Nov 04 '20 at 15:05
  • Read https://stackoverflow.com/questions/35553500/xmlhttprequest-cannot-load-xxx-no-access-control-allow-origin-header – MikiBelavista Nov 04 '20 at 15:10
  • @DavidYeiser It is important to understand who is going to access your domain and from where! – MikiBelavista Nov 04 '20 at 15:11
  • I updated the `origin` parameter to include the domain `['https://....com', 'https://js.stripe.com']` but with the same error. I suspect it might have something to do with the webfont files because the CSS file seems to go through fine (i.e. no error message about it) – David Yeiser Nov 04 '20 at 17:19

1 Answers1

0

The problem was not the code, but where it was located. In the Express/React setup, CORS must be set BEFORE express.static() is called.

The original code was like this (abridged):

app.use(express.static(CLIENT_BUILD_PATH))

app.use('/webfonts/stripe(/*)?', cors({
  origin: ['https://....com', 'https://js.stripe.com'],
  methods: ['GET', 'HEAD'],
  allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept']
}))

This sequence was trying to set Headers after the static content had been served, which I don’t think is possible.

Changing the code to this fixed the problem and everything works as expected now:

app.use('/webfonts/stripe(/*)?', cors({
  origin: ['https://....com', 'https://js.stripe.com'],
  methods: ['GET', 'HEAD'],
  allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept']
}))

app.use(express.static(CLIENT_BUILD_PATH))

A special thanks to Stripe customer support for figuring this out!

David Yeiser
  • 1,438
  • 5
  • 22
  • 33