Tuesday, January 5, 2016

How to fix CORS preflight issues in local grunt app w/ self-signed SSL cert

After many hours of headbanging, I finally succeeded in making xhr requests between my local webapp running via grunt serve and my secure ASP.NET ServiceStack application on a self-signed certificate.

I tried to use the chrome trick of --disable-web-security on a shortcut of chrome, and using the Allow-Control-Allow-Origin: * plugin, but still I was running into errors like

  • Response for preflight has invalid HTTP status code 404
  • The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
  • Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. 
I failed in trying to add CORS support to the server (which was okay-- we only want to bypass it for local testing).

With all these methods failing, I looked at the next logical progression: adding a proxy to the gruntfile to talk to the server. So I got my hands on the latest version of grunt-connect-proxy, followed their instructions for setting up, but I was still receiving issues. My requests would timeout at the proxy with the following error: Proxy error: ECONNRESET.

I finally found some others with the same problem in one of grunt-connect-proxy's github issues. The solution was to downgrade the version of grunt-connect-proxy. Low and behold, it works! My apps are talking to each other!


TL;DR: 
2. Install grunt-connect-proxy 0.1.10 
npm install grunt-connect-proxy@0.1.10



Here is the snippet of my gruntfile:


"use strict";
var LIVERELOAD_PORT, lrSnippet, mountFolder;
var serveStatic = require('serve-static');

LIVERELOAD_PORT = 35728;

lrSnippet = require("connect-livereload")({
 port: LIVERELOAD_PORT
});

mountFolder = function (connect, dir) {
 return serveStatic(require("path").resolve(dir));
};

module.exports = function (grunt) {
 var yeomanConfig;
 require("load-grunt-tasks")(grunt);
 require("time-grunt")(grunt);
 yeomanConfig = {
  app: "client",
  dist: "dist",
  docs: "documentation"
 };

 grunt.loadNpmTasks('grunt-connect-proxy');
 var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;

 try {
  yeomanConfig.app = require("./bower.json").appPath || yeomanConfig.app;
 } catch (_error) {}
 grunt.initConfig({
  yeoman: yeomanConfig,
  watch: {
   compass: {
    files: ["<%= yeoman.app %>/styles/**/*.{scss,sass}"],
    tasks: ["compass:server"]
   },
   less: {
    files: ["<%= yeoman.app %>/styles-less/**/*.less"],
    tasks: ["less:server"]
   },
   jade: {
    files: ["<%= yeoman.docs %>/jade/*.jade"],
    tasks: ["jade:docs"]
   },
   livereload: {
    options: {
     livereload: LIVERELOAD_PORT
    },
    files: [
                    "<%= yeoman.app %>/index.html",
                    "<%= yeoman.app %>/app/**/*.html",
                    "<%= yeoman.app %>/app/**/*.js",
                    "<%= yeoman.app %>/styles/**/*.scss",
                    "<%= yeoman.app %>/styles-less/**/*.less",
                    ".tmp/styles/**/*.css",
                    "<%= yeoman.app %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}",
                    "<%= yeoman.docs %>/jade/*.jade"
                ]
   }
  },
  connect: {
   options: {
    port: 9000,
    hostname: "localhost"
   },
   proxies: [{
     context: '/app', // the context of the data service
     host: 'localhost', // wherever the data service is running
     port: 44300, // the port that the data service is running on
     https: true,
     changeOrigin: true,
     rewrite: {
      '/app': ''
     }
     },
    {
     context: '/payment',
     host: 'localhost',
     port: 17333,
     https: false,
     changeOrigin: true,
     rewrite: {
      '/payment': ''
     }
    }],
   livereload: {
    options: {
     middleware: function (connect) {
      return [lrSnippet,
        mountFolder(connect, ".tmp"),
        mountFolder(connect, yeomanConfig.app),
          proxySnippet];
     }
    }
   },

5 comments:

  1. Excellent post!!! The strategy you have posted on this technology helped me to get into the next level and had lot of information in it.
    android training in chennai

    ReplyDelete
  2. UFC 212 Fight Card, Schedule, Date & Must-See Details. Watch UFC 212 Live Streaming Free Online. Aldo vs Holloway UFC Fight online preview.

    UFC 212
    UFC 212 Fight Card
    UFC 212 Card
    UFC 212 Live
    UFC 212 Live Stream
    UFC 212 PPV
    Aldo vs Holloway
    UFC 212 Aldo vs Holloway

    ReplyDelete
  3. Hi Joseph, Thanks a bunch for sharing this informative article with us. You know I am seeking for this kind of informative article related to cors preflight and recently I visit https://www.vpnsrus.com/what-is-a-vpn/ but didn't get any good info there. BTW thanks for sharing.

    ReplyDelete