AngularJS - html5Mode - не может GET/login - программирование
Подтвердить что ты не робот

AngularJS - html5Mode - не может GET/login

Привет, я создал одно приложение angularJS с йоменом, ворчанием и беседкой. Я включил html5Mode для приложения. И его работа. Но когда я обновляю страницу (localhost: 9000/login), она говорит

Cannot GET /login //or any url I type or refresh

Вот структура приложения

MainApp
|
|__app
|  |
|  |__bower_components
|  |
|  |__scripts
|  | |
|  | |__ app.js
|  | |
|  | |__contollers -- login.js, home.js, register.js
|  | |
|  | |__service -- js files
|  | |
|  | |__styles -- CSS files
|  | |
|  | |__views -- main.html, login.html, register.html,home.html
|  |
|  |__ index.html
|
|__ node_modules
|
|__ bower.json, Gruntfile.js, karma-conf.js, karma-e2e.conf.js, package.json

Вот моя маршрутизация app.js

'use strict';    
var superClientApp=angular.module('mainApp', ['ngCookies']);

//Define Routing for app
superClientApp.config(['$routeProvider', '$locationProvider',
  function($routeProvider,$locationProvider) {
    $routeProvider
    .when('/login', {
        templateUrl: 'login.html',
        controller: 'LoginController'
    })
    .when('/register', {
        templateUrl: 'register.html',
        controller: 'RegisterController'
      })
    .when('/home', {
       templateUrl: 'views/home.html',
       controller: 'homeController'
    })
    .otherwise({
       redirectTo: '/login'
    });
    $locationProvider.html5Mode(true);
}]);

Вот моя часть Gruntfile.js

'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  // configurable paths
  var yeomanConfig = {
    app: 'app',
    dist: 'dist'
  };

  try {
    yeomanConfig.app = require('./bower.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/{,*/}*.coffee'],
        tasks: ['coffee:test']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['copy:styles', 'autoprefixer']
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    autoprefixer: {
      options: ['last 1 version'],
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost'
      },
      proxies: [
        {
            context: '/serverApp',
            host: 'localhost',
            port: '8080',
            https: false,
            changeOrigin: false
        }
      ],
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              proxySnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },

Я прошел этот вопрос SO. И в соответствии с принятым ответом я изменил свой Gruntfile.js ниже.

'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;

var urlRewrite = require('grunt-connect-rewrite');

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  // configurable paths
  var yeomanConfig = {
    app: 'app',
    dist: 'dist'
  };

  try {
    yeomanConfig.app = require('./bower.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/{,*/}*.coffee'],
        tasks: ['coffee:test']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['copy:styles', 'autoprefixer']
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    autoprefixer: {
      options: ['last 1 version'],
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        base: 'app',
        middleware: function(connect, options) {
            // Return array of whatever middlewares you want
            return [
              // redirect all urls to index.html in build folder
              urlRewrite('app', 'index.html'),

              // Serve static files.
              connect.static(options.base),

              // Make empty directories browsable.
              connect.directory(options.base)
            ];
          }
      },
      proxies: [
        {
            context: '/serverApp',
            host: 'localhost',
            port: '8080',
            https: false,
            changeOrigin: false
        }
      ],
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              proxySnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },

Но все-таки я получаю ту же ошибку, когда обновляю страницу. Как это решить?

4b9b3361

Ответ 1

У вас должно быть решение на стороне сервера для перенаправления всего неразрешимого трафика на index.html

Я расскажу о версии htaccess этой версии и node.js. Я также реализовал это в spring -boot, но это было немного больше.

HTAccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /the-base-from-index.html/


    RewriteEngine on
    RewriteCond %{HTTP:X-Requested-With} !XMLHttpRequest$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule . index.html [L]
</IfModule>

Чтобы это работало, в конфигурации apache должен быть включен mod_rewrite, а также разрешить переопределение всех. Переписывание будет работать и в конфигурации apache.

Существует также условие, которое позволяет вам возвращать 404 на запрос ajax. Для того, чтобы это сработало, вы должны зарегистрировать предполетный заголовок для всего запроса $http, означающего, что они являются запросами xmlhttp. что-то вроде:

 myapp.config(function($httpProvider) {
      $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
 });

NODEJS

var express = require('express');
var bodyParser = require('body-parser')
var path = require('path')
var app = express();

app.use(express.static(__dirname + '/app'));
app.get('/*', function(req, res){
  res.sendFile(__dirname + '/app/index.html');
});

app.listen(9090);
console.log("Node Server Listening on port 9090");

Это грязь проста и может быть улучшена. А именно, с проверкой заголовков req для заголовка xmlhttp, аналогично тому, что делает пример htaccess.

Они получают общую идею. В основном любой трафик, который приведет к 404, будет обслуживаться index.html. Это позволяет вам продолжать статичный контент, но ваши маршруты (пока они фактически не существуют на диске в этом месте) вернут index.html.

Внимание! без решения, такого как заголовок preflight во всем запросе ajax, любой неразрешенный запрос шаблона приведет к бесконечному циклу и, вероятно, заблокирует ваш браузер.

Ответ 2

К настоящему времени это должна быть общая проблема с Angular для обработки маршрутизации.

Я нашел похожие проблемы на SO, которые предлагают тот же конфигуратор html5 для обхода метода hashbang - см. AngularJS: как включить $locationProvider.html5Mode с deeplinking Также может начаться учебник по scotch.io https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag.

Но самое главное, я помню, что это тот, который сделал трюк.

https://gist.github.com/leocaseiro/4305e06948aa97e77c93

Я запускаю веб-сервер Apache. Я не вспоминаю, на каком уровне (глобально или за приложение) я сделал конфигурацию, но лучше всего было бы проконсультироваться с документами веб-сервера, Apache был хорош.

Ответ 3

Это происходит потому, что когда вы нажимаете обновление, ваш браузер будет пытаться получить/войти с сервера, а не через поставщика услуг на стороне клиента. Я предполагаю, что /login возвращает 404 в вашем случае.

Вам нужно получить сервер, который фактически служит вашим файлам для обслуживания /index.html, даже если запрос был сделан для /login. Как вы это делаете, это зависит от настройки вашей серверной части. Вы можете сделать это с помощью динамического сценария или правила перезаписи.

Если вы не можете управлять сервером таким образом, то htmlmode, вероятно, не для вас печально.

Ответ 4

добавить 'views/login.html' в сторону вашего шаблонаUrl надеюсь, что это сработает

Ответ 5

добавьте этот код в server.js после всех маршрутов

app.use('/*',function(req, res) {
    res.sendfile(__dirname + '/public/index.html');
});

Ответ 6

Вы пытались использовать абсолютные пути в $routeProvider?

.when('/login', {
  templateUrl: '../app/scripts/views/login.html',
  controller: 'loginController'
},
...