Angular-Browersync-Express不能从客户端快递后端路线上发布



我正在使用一个Angular-Gulp-browsersync-express应用程序,并且我很难获得Angular的$ HTTP资源来向我的Express Server发布简单的"联系我们"表单。

每当我尝试提交表格时,我会收到以下错误:

POST http://localhost:8080/submitContactUsForm 404 (Not Found)
Cannot POST /submitContactUsForm

要保持领先地位,与后端相比,我在前端的工作经验要多得多,因此很可能我的服务器设置错误。

这是我的Express Server:

'use strict';
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var http = require('http');
var routes = require('.././src/index.module.js');
// var contactController = require('.././api/http/controllers/contactcontroller.js');
// require database data modeling via mongoose
var mongoose = require('mongoose');
// Express Session allows us to use Cookies to keep track of
// a user across multiple pages. We also need to be able to load
// those cookies using the cookie parser
var session = require('express-session');
var cookieParser = require('cookie-parser');
// Flash allows us to store quick one-time-use messages
// between views that are removed once they are used.
// Useful for error messages.
var flash = require('connect-flash');

// Use express and set it up
var app = express();
app.use(cors());
app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.post('/submitContactUsForm', function(req, res) {
console.log('it hit the server');
})
var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync').create();
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var proxyMiddleware = require('http-proxy-middleware');
 function browserSyncInit(baseDir, browser) {
  browser = browser === undefined ? 'default' : browser;
 var routes = null;
 if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
 routes = {
  '/bower_components': 'bower_components'
  };
 }
browserSync.instance = browserSync.init({
 startPath: '/',
 cors: true,
 browser: browser,
 port: 8080,
 server: {
  baseDir: baseDir,
  routes: routes,
  middleware: function (req, res, next) {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept");
      res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
      next();
   }
  },
 });
}
browserSync.use(browserSyncSpa({
 selector: '[ng-app]'// Only needed for angular apps
}));
gulp.task('serve', ['setenvconstants','watch'], function () {
 browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});
gulp.task('serve:dist', ['setenvconstants','build'], function () {
 browserSyncInit(conf.paths.dist);
});
gulp.task('serve:e2e', ['inject'], function () {
 browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
 browserSyncInit(conf.paths.dist, []);
});

这是我要发布的角控制器:

(function() {
 'use strict';
angular
    .module('commonSenseDietApp')
    .controller('ContactController', ContactController);

 function ContactController($http, $log) {
    // controllerAs syntax
    var vm = this;
 vm.contactInfo = {
  email: vm.email
 }
 vm.processContactForm = function() {
  return $http.post('/submitContactUsForm', vm.contactInfo)
      .then(returnSendSuccessful)
      .catch(sendFail);
  function returnSendSuccessful(response) {
    $log.log(response.data);
    return response.data;
  }
  function sendFail(err) {
    return $log.error(err.data);
  }
 }

 }
})();

这是我的客户端路线:

(function() {
 'use strict';
 angular
 .module('commonSenseDietApp')
 .config(routeConfig);
 function routeConfig($routeProvider) {
 // Home Page
 $routeProvider
 .when('/', {
  templateUrl: 'app/views/pages/home.html',
  controller: 'MainController',
  controllerAs: 'vm'
 })
 .otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
 });
 // About Page
 $routeProvider
 .when('/about', {
  templateUrl: 'app/views/static/about.html'
 })
 .otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
 });
// Terms of Use Page
$routeProvider
.when('/terms-of-use', {
  templateUrl: 'app/views/static/terms-of-use.html'
})
.otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
});
// Privacy Policy Page
$routeProvider
.when('/privacy-policy', {
  templateUrl: 'app/views/static/privacy-policy.html'
})
.otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
});
// Contact Us Page
$routeProvider
.when('/contact', {
  templateUrl: 'app/views/pages/contact.html',
  controller: 'ContactController',
  controllerAs: 'vm'
})
.otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
});
// Answer Page
$routeProvider
.when('/answer', {
  templateUrl: 'app/views/pages/answer.html',
  controller: 'AnswerController',
  controllerAs: 'vm'
})
.otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
});
// How It Works Page
$routeProvider
.when('/how-it-works', {
  templateUrl: 'app/views/static/how-it-works.html'
})
.otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
});
 // Algorithm Explainer Page
 $routeProvider
 .when('/meet-ONNA', {
  templateUrl: 'app/views/static/meet-ONNA.html'
 })
 .otherwise({
  controller: 'Error404Controller',
  templateUrl: 'app/views/errors/404.html'
 });
}
})();

这是我的联系表格标记:

<section>
 <div class="contact-us-title">
    <h1>Contact Us</h1>
 </div>
 <form class="contact-us-form" name="contactUsForm" ng-submit="vm.processContactForm()">
    <div class="form-group">
        <input placeholder="name" type="text" name="name" ng-model="vm.name" class="form-control" required />
        <span class="label label-danger" ng-show="vm.submitted && contact-us-form.name.$error.required">Required!</span>
    </div>
    <div class="form-group">
        <input placeholder="Email" type="email" name="email" ng-model="vm.email" class="form-control" required />
        <span class="label label-danger" ng-show="vm.submitted && contact-us-form.email.$error.required">Required!</span>
  <span class="label label-danger" ng-show="vm.submitted && contact-us-form.$error.email">Invalid email!</span>
    </div>
    <div class="form-group">
        <input name="headline" placeholder="Headline" type="text" ng-model="vm.headline" class="form-control" required/>
        <span class="label label-danger" ng-show="vm.submitted && contact-us-form.headline.$error.required">Required!</span>
    </div>
    <div class="form-group">
        <textarea name="message" placeholder="Message" type="textbox" ng-model="vm.message" class="form-control" required></textarea>
        <span class="label label-danger" ng-show="vm.submitted && contact-us-form.subjectList.$error.required">Required!</span>
    </div>

    <input type="submit" id="submit-contact-form-btn">
  </form>
</section>

我也看不到任何在终端中登录控制台的东西。对此的任何见解都将非常有帮助,并且非常感谢。

eureka我找到了答案!

证明,我缺乏与BrowerSync一起表现出色的经验,这对我来说肯定是一个障碍。答案在于代理浏览器表达和使用Gulp-Nodemon软件包。经过一些重组后,我有了正确的设置:

我的浏览器同步服务器和Gulp Init任务:

'use strict';
var path = require('path');
var port = process.env.PORT || 8080;
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync').create();
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var proxyMiddleware = require('http-proxy-middleware');
var nodemon = require('gulp-nodemon');
var reload = browserSync.reload;
function browserSyncInit(baseDir, browser) {
 var routes = null;
 if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
  routes = {
   '/bower_components': 'bower_components'
  };
 }
 browserSync.instance = browserSync.init({
  startPath: '/',
  cors: true,
  browser: browser = browser === undefined ? 'default' : browser,
  proxy: 'http://localhost:8081',
  port: port
 // https: true
 });
}
browserSync.use(browserSyncSpa({
 selector: '[ng-app]' // Only needed for angular apps
}));
// Run Gulp tasks
gulp.task('serve', ['browser-sync','setenvconstants','watch']);
gulp.task('browser-sync', ['nodemon'], function () {
 browserSyncInit([path.join(conf.paths.tmp, '/serve'),   conf.paths.src]);
});
gulp.task('serve:dist', ['setenvconstants','build'], function () {
 browserSyncInit(conf.paths.dist);
});
gulp.task('serve:e2e', ['inject'], function () {
 browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
 browserSyncInit(conf.paths.dist, []);
});
gulp.task('nodemon', [], function(done) {
 var running = false;
 return nodemon({
  script: 'api/app.js',
  watch: ['api/**/*.*', 'src/**/*.*']
 })
 .on('start',function() {
  if (!running) {
    done();
  }
  running = true;
 })
 .on('restart', function() {
  setTimeout(function(){
    reload();
  }, 500);
 });
});

我的Express Server:

var express = require('express');
var bodyParser = require('body-parser');
var http = require('http');
var port = process.env.PORT || 8081;
var cors = require('cors');
var path = require('path');
var publicRoutes = require('./http/routes/web.js');
// require database data modeling via mongoose
var mongoose = require('mongoose');
// Express Session allows us to use Cookies to keep track of
// a user across multiple pages. We also need to be able to load
// those cookies using the cookie parser
var session = require('express-session');
var cookieParser = require('cookie-parser');
// Flash allows us to store quick one-time-use messages
// between views that are removed once they are used.
// Useful for error messages.
var flash = require('connect-flash');
// Use Express and set it up
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
// Parse requests to JSON
app.use(bodyParser.json({type: '*/*', limit: '50mb'}));
// set Jade as the view engine
app.set('view engine', 'jade');
// tell server where to find our views
app.set('views', __dirname + '/.././src/app/views');
// make sure bower components are installed.
app.use('/underscore',    express.static(path.resolve('.././node_modules/underscore')));
// tell our server where to find static assets depending on the environment.
process.env.NODE_ENV == 'production' ?  app.use(express.static(path.join(__dirname + '/../..'))) :  app.use(express.static(path.join(__dirname + '/.././dist')));
// enable cors
app.use(cors({
 "origin": "*",
 "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
 "allowedHeaders": ["Origin, X-Requested-With, Content-Type, Accept, Authorization"],
 "preflightContinue": false
}));
// Pull in our public routes
app.use('/api', publicRoutes);
// Listen
app.listen(port, function(error) {
 if (error) {
  console.error(error);
 } else {
  console.info("==> 🌎  Listening on port %s. Visit http://localhost:%s/ in your browser.", port, port);
 }
});

我现在可以从Angular Controller $ http. post考虑我的Express Server中的路由前缀:

vm.processContactForm = function() {
  return $http.post('/api/submitContactUsForm', vm.contactInfo)
      .then(returnSendSuccessful)
      .catch(sendFail);
  function returnSendSuccessful(response) {
    $log.log(response);
    // return response.data;
  }
  function sendFail(err) {
    return $log.error(err.data);
  }
}

我现在遇到的唯一问题是...

process.env.NODE_ENV == 'production' ? app.use(express.static(path.join(__dirname + '/.././src'))) : app.use(express.static(path.join(__dirname + '/.././dist')));

其中,'/dist'的服务很好,但是'/src'仅在我的本地主机上提供空白index.html页面。我将把它作为一个新问题发布,并考虑解决此问题。感谢您的帮助!

最新更新