1

I am having a problem in loading my fonts from a link from my website. ON what I have seen there is an error in my server.js that CORS is not present in my header. Now, My problem is How will I insert the header into my server.js Can someone help me?

Here is the error

Font from origin 'my website link' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3001' is therefore not allowed access

const app = express();

//
// Tell any CSS tooling (such as Material UI) to use all vendor prefixes if the
// user agent is not known.
// -----------------------------------------------------------------------------
global.navigator = global.navigator || {};
global.navigator.userAgent = global.navigator.userAgent || 'all';

//
// Register Node.js middleware
// -----------------------------------------------------------------------------
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

//
// Authentication
// -----------------------------------------------------------------------------
app.use(expressJwt({
  secret: auth.jwt.secret,
  credentialsRequired: false,
  getToken: req => req.cookies.id_token,
}));
app.use(passport.initialize());

app.get('/login/facebook',
  passport.authenticate('facebook', { scope: ['email', 'user_location'], session: false })
);
app.get('/login/facebook/return',
  passport.authenticate('facebook', { failureRedirect: '/login', session: false }),
  (req, res) => {
    const expiresIn = 60 * 60 * 24 * 180; // 180 days
    const token = jwt.sign(req.user, auth.jwt.secret, { expiresIn });
    res.cookie('id_token', token, { maxAge: 1000 * expiresIn, httpOnly: true });
    res.redirect('/');
  }
);

//
// Register API middleware
// -----------------------------------------------------------------------------
app.use('/graphql', expressGraphQL(req => ({
  schema,
  graphiql: true,
  rootValue: { request: req },
  pretty: process.env.NODE_ENV !== 'production',
})));

//
// Register server-side rendering middleware
// -----------------------------------------------------------------------------
app.get('*', async (req, res, next) => {
  try {
    let css = [];
    let statusCode = 200;
    const data = { title: '', description: '', style: '', script: assets.main.js, children: '' };

    await UniversalRouter.resolve(routes, {
      path: req.path,
      query: req.query,
      context: {
        insertCss: (...styles) => {
          styles.forEach(style => css.push(style._getCss())); // eslint-disable-line no-underscore-dangle, max-len
        },
        setTitle: value => (data.title = value),
        setMeta: (key, value) => (data[key] = value),
      },
      render(component, status = 200) {
        css = [];
        statusCode = status;
        data.children = ReactDOM.renderToString(component);
        data.style = css.join('');
        return true;
      },
    });

    const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);

    res.status(statusCode);
    res.send(`<!doctype html>${html}`);
  } catch (err) {
    next(err);
  }
});

//
// Error handling
// -----------------------------------------------------------------------------
const pe = new PrettyError();
pe.skipNodeFiles();
pe.skipPackage('express');

app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  console.log(pe.render(err)); // eslint-disable-line no-console
  const statusCode = err.status || 500;
  const html = ReactDOM.renderToStaticMarkup(
    <Html
      title="Internal Server Error"
      description={err.message}
      style={errorPageStyle._getCss()}
      userAgent={req.headers['user-agent']}> // eslint-disable-line no-underscore-dangle
      {ReactDOM.renderToString(<ErrorPage error={err} />)}
    </Html>
  );
  res.status(statusCode);
  res.send(`<!doctype html>${html}`);
});

//
// Launch the server
// -----------------------------------------------------------------------------
/* eslint-disable no-console */
models.sync().catch(err => console.error(err.stack)).then(() => {
  app.listen(port, () => {
    console.log(`The server is running at http://localhost:${port}/`);
  });
});
/* eslint-enable no-console */
yoges nsamy
  • 1,275
  • 1
  • 16
  • 29
dczii
  • 539
  • 5
  • 10
  • 20

3 Answers3

4

Straight from this website, on enabling CORS in express:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/', function(req, res, next) {
  // Handle the get for this route
});

app.post('/', function(req, res, next) {
 // Handle the post for this route
});
KumarM
  • 1,669
  • 1
  • 18
  • 26
  • A nice improvement for your answer would be to use Router instead of app. – Guillermo Aug 12 '16 at 03:20
  • @Guillermo Thanks for the suggestion. Sounds interesting. Any links that can help me learn more about it? Or did you mean something like react-router? – KumarM Aug 12 '16 at 03:23
  • I have tried adding app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); but I still get the same error and upon loading the fonts there is still no Access control allow origin in the header – dczii Aug 12 '16 at 03:24
  • @dczii So did that work? Have you tried it adding before your authentication setup in that file and see if it helps? – KumarM Aug 12 '16 at 03:26
2

You can insert the headers as showed below. This is working on my project without any issues.

// Where app -> const app = express(); 
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

By the way, you can improve your code separating routing logic from app.js, and using Router: http://expressjs.com/es/api.html#router

Hope that it helps.

Guillermo
  • 1,493
  • 3
  • 16
  • 35
  • 1
    I have tried adding the code but I still get the same error :( – dczii Aug 12 '16 at 03:31
  • @dczii can you please post a gist with your app.js? – Guillermo Aug 12 '16 at 03:35
  • @dczii I may be expressed myself in a wrong way, I'll need the app.js of your express.js project. – Guillermo Aug 12 '16 at 03:38
  • I am using express.js as a module for my project so I didn't edit anything from my expressjs module – dczii Aug 12 '16 at 03:40
  • @dczii express js is not a module but a whole framework, in the other hand, the issue is raised on the server that you're hitting to request the fonts, so there should the cors solution be applied. Is that website under your management? – Guillermo Aug 12 '16 at 03:41
  • wow thank you for that info, I am still a newbie in nodejs and expressjs. Yes the website is under my management and we are using AWS. so does it mean the problem is from the server where my fonts are? – dczii Aug 12 '16 at 03:45
  • If you're using AWS and S3, then you should set the headers there, not in the app, that is a very common scenario, there are tons of answers about that as for example: http://stackoverflow.com/questions/17533888/s3-access-control-allow-origin-header – Guillermo Aug 12 '16 at 03:46
  • CORS is about hitting a domain different than the domain that started the request. If you hit something of your domain, where you have set the cors headers, then you shouldnt have CORS issues. You're having CORS issues due that your fonts stored on S3, or Cloudfront doesnt have the CORS headers set on AWS. – Guillermo Aug 12 '16 at 03:48
  • You don´t need to add anything to your site, just add the headers to your static files bucket, and everything will work fine. – Guillermo Aug 12 '16 at 03:49
1

Install cors from npm,

npm install cors

And, add it as middleware

app.use(cors());

Goog luck!

Ritwik
  • 1,597
  • 16
  • 17