การโหลดหน้าซ้ำให้คำขอ GET ไม่ถูกต้องด้วยโหมด AngularJS HTML5


193

ฉันต้องการเปิดใช้งานโหมด HTML5 สำหรับแอปของฉัน ฉันได้ใส่รหัสต่อไปนี้สำหรับการกำหนดค่าตามที่แสดงที่นี่ :

return app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {

    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix = '!';

    $routeProvider.when('/', {
        templateUrl: '/views/index.html',
        controller: 'indexCtrl'
    });
    $routeProvider.when('/about',{
        templateUrl: '/views/about.html',
        controller: 'AboutCtrl'
    });

ที่คุณสามารถดูผมใช้$locationProvider.html5modeและผมเปลี่ยนการเชื่อมโยงทั้งหมดของฉันที่จะไม่รวมng-href/#/

ปัญหา

ในขณะที่ฉันสามารถไปlocalhost:9000/และดูหน้าดัชนีและนำทางไปยังหน้าเว็บอื่น ๆ localhost:9000/aboutเช่น

อย่างไรก็ตามปัญหาเกิดขึ้นเมื่อฉันรีเฟรชlocalhost:9000/aboutหน้า ฉันได้รับผลลัพธ์ต่อไปนี้:Cannot GET /about

ถ้าฉันดูเครือข่ายโทร:

Request URL:localhost:9000/about
Request Method:GET

ในขณะที่ถ้าฉันไปที่localhost:9000/แล้วคลิกที่ปุ่มที่นำทางไปยัง/aboutฉันได้รับ:

Request URL:http://localhost:9000/views/about.html

ซึ่งแสดงผลหน้าเว็บได้อย่างสมบูรณ์แบบ

ฉันจะเปิดใช้งานเชิงมุมเพื่อรับหน้าที่ถูกต้องเมื่อฉันรีเฟรช?



1
ฉันแก้มันให้ฉัน ดูที่นี่stackoverflow.com/questions/22394014/…
Sasha B.

คำตอบ:


99

จากเอกสารเชิงมุม

ฝั่งเซิร์ฟเวอร์
การใช้โหมดนี้ต้องมีการเขียน URL ใหม่ในฝั่งเซิร์ฟเวอร์โดยทั่วไปคุณต้องเขียนลิงค์ทั้งหมดของคุณไปยังจุดเริ่มต้นของแอปพลิเคชันของคุณ (เช่น index.html)

เหตุผลนี้คือเมื่อคุณเยี่ยมชมหน้าแรก ( /about) เช่นหลังจากรีเฟรชเบราว์เซอร์ไม่มีทางรู้ว่านี่ไม่ใช่ URL จริงดังนั้นจึงไปข้างหน้าและโหลด อย่างไรก็ตามหากคุณโหลดหน้ารูทขึ้นก่อนและรหัสจาวาสคริปต์ทั้งหมดเมื่อคุณนำทางไปที่/aboutAngular สามารถเข้าไปที่นั่นก่อนที่เบราว์เซอร์จะพยายามโจมตีเซิร์ฟเวอร์และจัดการมันตามลำดับ


21
เมื่อมีข้อความแจ้งว่า "คุณต้องเขียนลิงก์ทั้งหมดของคุณใหม่ไปยังจุดเริ่มต้นของแอปพลิเคชันของคุณ (เช่น index.html)" สิ่งนี้หมายความว่าอย่างไร มันหมายความว่าฉันต้องไปที่ของฉัน$routeProviderและเปลี่ยนเส้นทางของแต่ละtemplateUrlเช่นจากtemplateUrl : '/views/about.html',ไปtemplateUrl : 'example.com/views/about.html',?

7
ไม่กฎของคุณใน $ routeProvider ควรอยู่เหมือนเดิม คำตอบหมายถึง "ฝั่งเซิร์ฟเวอร์" มันหมายถึงการเปลี่ยนเส้นทางบนเซิร์ฟเวอร์ที่ให้หน้า html เชิงมุมของคุณ ก่อนที่คำขอแต่ละคำขอจะเข้าสู่แอปเชิงมุมของคุณจะต้องผ่านการกำหนดเส้นทางฝั่งเซิร์ฟเวอร์ก่อนซึ่งควรเขียนคำขอทั้งหมดใหม่ให้ชี้ไปที่จุดเข้าใช้แอปเชิงมุมของคุณ (เช่น 'index.html' หรือ '/' ขึ้นอยู่กับว่า เส้นทางทำงาน)
marni

ในกรณีที่ฉันให้บริการ minified index.html ผ่าน CDN บางส่วนกว่ากลไกการกำหนดเส้นทางนี้จะดำเนินการอย่างไร
CrazyGeek


5
บทความที่ดีสำหรับ apache มีตัวอย่าง htaccess: ngmilk.rocks/2015/03/09/…
Alcalyn

63

มีบางสิ่งในการตั้งค่าเพื่อให้ลิงก์ในเบราว์เซอร์ของคุณดูเหมือนhttp://yourdomain.com/pathและสิ่งเหล่านี้คือการกำหนดค่าเชิงมุม + เซิร์ฟเวอร์ของคุณ

1) AngularJS

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

2) ฝั่งเซิร์ฟเวอร์เพียงแค่ใส่.htaccessในโฟลเดอร์รูทของคุณและวางสิ่งนี้

RewriteEngine On 
Options FollowSymLinks

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /#/$1 [L]

สิ่งที่น่าสนใจมากขึ้นในการอ่านเกี่ยวกับโหมด HTML5 ใน angularjs และการตั้งค่าที่จำเป็นต่อสภาพแวดล้อมที่แตกต่างกันhttps://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server -to-work-with-html5mode นอกจากนี้คำถามนี้อาจช่วยให้คุณ$ location / การสลับระหว่าง html5 และ hashbang mode / link rewriting


สวัสดี ฉันลองวิธีแก้ปัญหาข้างต้นทำการเปลี่ยนแปลงในไฟล์ปรับแต่งของฉัน แต่ก็ยังไม่ได้ผล การรีเฟรช URL ยังคงมีข้อผิดพลาด "404 ไม่พบ"
kTn

ฉันจะเปลี่ยนเส้นทาง / เขียนใหม่ในแอปที่ปรับใช้ใน Websphere ได้อย่างไร
Gary

ฉันไม่เห็นว่าทำไมไม่!
สูบบุหรี่

36

ฉันมีปัญหาที่คล้ายกันและฉันแก้ไขได้โดย:

  • ใช้<base href="https://stackoverflow.com/index.html">ในหน้าดัชนี

  • การใช้มิดเดิลแวร์จับเส้นทางทั้งหมดในโหนด / เซิร์ฟเวอร์ Express ของฉันดังต่อไปนี้ (วางไว้หลังเราเตอร์):

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

ฉันคิดว่าคุณควรจะได้รับและทำงาน

หากคุณใช้เซิร์ฟเวอร์ apache คุณอาจต้องการ mod_rewrite ลิงก์ของคุณ ไม่ยากที่จะทำ การเปลี่ยนแปลงเพียงเล็กน้อยในไฟล์ปรับแต่ง

ทั้งหมดที่สมมติว่าคุณเปิดใช้งาน html5mode บน angularjs ตอนนี้ โปรดทราบว่าในเชิง 1.2 จะไม่แนะนำให้ประกาศ URL พื้นฐานอีกต่อไป


1
วิธีนี้ใช้ได้ผลกับฉันด้วยการตั้งค่า: <base href="https://stackoverflow.com/">และเพิ่มการกำหนดเส้นทางด่วนที่คุณแนะนำ ขอบคุณมาก
Gilad Peleg

ตอนนี้, คุณยังต้องใช้ url-rewrite บนเซิร์ฟเวอร์หลังจากติดตั้ง<base href="https://stackoverflow.com/index.html">หรือไม่?
โคดี

ใช่คุณสามารถเห็นการเขียน url ใหม่เป็นวิธีการตั้ง url พื้นฐานของแอปพลิเคชั่น / เว็บไซต์ของคุณด้วย (รวมโดเมน) ข้อความ 'html ฐาน' เป็นเพียงวิธีหนึ่งเพื่อให้แน่ใจว่าลิงก์ที่เกี่ยวข้องทั้งหมดนั้นได้รับมาอย่างถูกต้องจากฐานเดียวกัน URL ฐานไม่จำเป็นอย่างยิ่งหากลิงก์ของคุณสมบูรณ์
Taye

1
เมื่อฉันใช้สิ่งนี้ฉันเพิ่งเห็นรหัส html ของตัวเองบนหน้าเว็บไม่แสดงผลเป็นหน้าจริง
โนอาห์

2
คำตอบนี้สมควรได้รับสามดาว! ขอบคุณที่ให้คำตอบที่ตรงไปตรงมา ทุกคนเพียงแค่ทำซ้ำบรรทัดเดียวกันเกี่ยวกับ "จำเป็นต้องทำการเปลี่ยนเส้นทางเซิร์ฟเวอร์"
Ahmed Haque

27

โซลูชั่นสำหรับ BrowserSync และอึก

จากhttps://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643

ติดตั้งครั้งแรกconnect-history-api-fallback:

npm --save-dev install connect-history-api-fallback

จากนั้นเพิ่มไปยัง gulpfile.js ของคุณ:

var historyApiFallback = require('connect-history-api-fallback');

gulp.task('serve', function() {
  browserSync.init({
    server: {
      baseDir: "app",
      middleware: [ historyApiFallback() ]
    }
  });
});

โอ้โห! ในที่สุดก็บรรเทาจากการพัฒนามุมมองเชิงมุม! และเป็นโบนัสเส้นทาง URL มาตรฐาน (โดยไม่มีแฮช - แบง) ด้วย! ขอบคุณ!
บิตน้อยลง

1
ทำงานเหมือนจับใจ ... ขอบคุณมาก!
Nishanth Nair

1
หากคุณใช้พอร์ตเฉพาะ (เช่นเทมเพลต Ionic ที่ว่างทำงานบนพอร์ต 8100) เพียงเพิ่มคุณสมบัติเพิ่มเติมหลังจากเซิร์ฟเวอร์เช่นserver: { ... }, port: 8100จากนั้นเพิ่มserveงานลงในงาน gulp เริ่มต้นของคุณ (เช่นgulp.task('default', ['sass', 'serve']);) จากนั้นคุณสามารถเรียกใช้แอปได้ โดยไม่ต้องมีข้อผิดพลาดเมื่อคุณเบราว์เซอร์รีเฟรชหน้าเว็บโดยใช้Cannot GET ... gulpโปรดทราบว่าการเรียกใช้เซิร์ฟเวอร์โดยionic serveยังคงพบข้อผิดพลาด
ลุคเชิน

สิ่งนี้ทำงานได้ดีเมื่อฉันใช้เบราว์เซอร์การพัฒนาใน prod ฉันกำลังเรียกใช้แอปพลิเคชันเป็นแอปด่วนและเปลี่ยนเส้นทางทั้งหมดไปยังแอปเชิงมุมเป็น app.get ('*', ฟังก์ชัน (req, res) {req.session.valid = true ; res.redirect ('/');}); หน้าไม่โหลดเมื่อให้เส้นทางโดยตรงหรือไม่
นาย AJ

13

คุณต้องกำหนดค่าเซิร์ฟเวอร์ของคุณเพื่อเขียนทุกอย่างเป็น index.html เพื่อโหลดแอป:

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#wiki-how-to-configure-your-server-to-work-with-html5mode


1
เพอร์เฟปัญหาสำหรับผมใช้ Laravel Forge บทบัญญัติเซิร์ฟเวอร์ที่มีเส้น Nginx ที่เกี่ยวข้องเป็นแทนการที่จำเป็นtry_files $uri $uri/ /index.php?... index.htmlขอบคุณสำหรับลิงค์!
CJ Thompson

ควรเป็นคำตอบอันดับต้นให้ทุกสถานการณ์ไม่ว่าเซิร์ฟเวอร์ของคุณ ทำงานอย่างสมบูรณ์แบบกับ NodeJS
Joe Lloyd

10

ฉันเขียนมิดเดิลแวร์เชื่อมต่ออย่างง่ายสำหรับจำลอง url-rewriting ในโครงการ grunt https://gist.github.com/muratcorlu/5803655

คุณสามารถใช้สิ่งต่อไปนี้:

module.exports = function(grunt) {
  var urlRewrite = require('grunt-connect-rewrite');

  // Project configuration.
  grunt.initConfig({
    connect: {
      server: {
        options: {
          port: 9001,
          base: 'build',
          middleware: function(connect, options) {
            // Return array of whatever middlewares you want
            return [
              // redirect all urls to index.html in build folder
              urlRewrite('build', 'index.html'),

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

              // Make empty directories browsable.
              connect.directory(options.base)
            ];
          }
        }
      }
    }
  })
};

มีวิธีการในการเขียน URL ใหม่ด้วยตนเอง$routeProviderหรือไม่?

1
ฉันurlRewriteไม่ได้รับการเตือนเมื่อพยายามเรียกใช้และฉันพบปัญหาในการเชื่อมต่อที่ถูกต้องกับการเขียนซ้ำที่ฉันสามารถใช้งานได้

แสดงข้อผิดพลาด "Object build ไม่มีเมธอด 'initConfig' ใช้ - บังคับให้ดำเนินการต่อ"
edonbajrami

8

หากคุณอยู่ใน. NET stack ด้วย MVC กับ AngularJS นี่คือสิ่งที่คุณต้องทำเพื่อลบ '#' ออกจาก url:

  1. ตั้งค่า href ฐานของคุณในหน้า _Layout ของคุณ: <head> <base href="https://stackoverflow.com/"> </head>

  2. จากนั้นเพิ่มสิ่งต่อไปนี้ในแอปเชิงมุมของคุณ: $locationProvider.html5Mode(true)

  3. ด้านบนจะลบ '#' ออกจาก url แต่การรีเฟรชหน้าจะไม่ทำงานเช่นถ้าคุณอยู่ใน "yoursite.com/about" การรีเฟรชหน้าจะทำให้คุณมี 404 นี่เป็นเพราะ MVC ไม่ทราบเกี่ยวกับการจัดเส้นทางเชิงมุมและด้วยรูปแบบ MVC จะค้นหาหน้า MVC สำหรับ 'เกี่ยวกับ' ซึ่งไม่มีอยู่ในเส้นทางการกำหนดเส้นทาง MVC วิธีแก้ปัญหาสำหรับสิ่งนี้คือการส่งคำขอหน้า MVC ทั้งหมดไปยังมุมมอง MVC เดียวและคุณสามารถทำได้โดยเพิ่มเส้นทางที่ดึงดูด URL ทั้งหมด


routes.MapRoute(
        name: "App",
        url: "{*url}",
        defaults: new { controller = "Home", action = "Index" }
    );

8

IIS URL กฎการเขียนซ้ำเพื่อป้องกันข้อผิดพลาด 404 หลังจากรีเฟรชหน้าเว็บใน html5mode

สำหรับการทำงานเชิงมุมภายใต้ IIS บน Windows

<rewrite>
  <rules>
    <rule name="AngularJS" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>

NodeJS / ExpressJS Routes เพื่อป้องกันข้อผิดพลาด 404 หลังจากรีเฟรชหน้าเว็บใน html5mode

สำหรับการวิ่งเชิงมุมภายใต้ Node / Express

var express = require('express');
var path = require('path');
var router = express.Router();

// serve angular front end files from root path
router.use('/', express.static('app', { redirect: false }));

// rewrite virtual urls to angular app to enable refreshing of internal pages
router.get('*', function (req, res, next) {
    res.sendFile(path.resolve('app/index.html'));
});

module.exports = router;

ข้อมูลเพิ่มเติมที่: AngularJS - เปิดใช้งานการรีเฟรชหน้าโหมด HTML5 โดยไม่มีข้อผิดพลาด 404 ใน NodeJS และ IIS


ขอบคุณกฎ IIS ช่วยฉันด้วยแอป angular2 ที่ปรับใช้ในสีฟ้าซึ่งไม่สามารถนำไปยังเส้นทางลูกได้
bitsprint

ฉันไม่สามารถขอบคุณมากพอสำหรับการแก้ปัญหาสำหรับ IIS (localhost ใน VS 2013) กระแทกหัวของฉันนานพอที่จะหงุดหงิดในที่สุดก็พบคำตอบนี้ ทำงานเหมือนจับใจ
ฟลอริด้า G.

5

<base href="https://stackoverflow.com/"/>เป็นคนอื่นได้กล่าวถึงคุณจะต้องเขียนเส้นทางบนเซิร์ฟเวอร์และการตั้งค่า

สำหรับgulp-connect:

npm install connect-pushstate

var gulp = require('gulp'),
  connect = require('gulp-connect'),
  pushState = require('connect-pushstate/lib/pushstate').pushState;
...
connect.server({
  ...
  middleware: function (connect, options) {
    return [
      pushState()
    ];
  }
  ...
})
....

4

ฉันใช้ apache (xampp) กับสภาพแวดล้อม dev และ apache ของฉันในการผลิตเพิ่ม:

errorDocument 404 /index.html

เพื่อ. htaccess แก้ปัญหานี้ให้ฉันได้


4

สำหรับ Grunt และ Browsersync ให้ใช้ connect-modrewrite ที่นี่

var modRewrite = require('connect-modrewrite');    


browserSync: {
            dev: {
                bsFiles: {

                    src: [
                        'app/assets/css/*.css',
                        'app/*.js',
                        'app/controllers/*.js',
                        '**/*.php',
                        '*.html',
                        'app/jade/includes/*.jade',
                        'app/views/*.html',
               ],
            },
        options: {
            watchTask: true,
            debugInfo: true,
            logConnections: true,
            server: {
                baseDir :'./',
                middleware: [
                       modRewrite(['!\.html|\.js|\.jpg|\.mp4|\.mp3|\.gif|\.svg\|.css|\.png$ /index.html [L]'])
                ]
            },

            ghostMode: {
                scroll: true,
                links: true,
                forms: true
                    }
                }
            }
        },

มีคำตอบทั้งหมด 15 ข้อที่อยู่ในช่วงเอว 1. npm install connect-modrewrite --save2. require in gruntfile3. คัดลอกเซิร์ฟเวอร์ข้างต้น obj
Omar

ขอบคุณสิ่งนี้ใช้ได้สำหรับฉันใน gulp 4 ด้วยการตั้งค่า browserSync
Abdeali Chandanwala

ดีใจที่มันช่วย @Abdeali Chandanwala!
MrThunder

@Omar ฉันไม่เห็นด้วยกับคุณผู้ใช้ขั้นสูงที่น้อยกว่าเช่นฉันได้รับประโยชน์จากการเห็นวิธีเพิ่มลงใน gulpfile ที่ดีที่สุดคือต้องจำไว้ว่าคนที่มีความรู้ในระดับที่แตกต่างกันและเพียงแค่การเขียนต้องใช้ใน gruntfile จะไม่เป็นประโยชน์เพราะฉันจะสมมติว่าพวกเขาเข้าใจวิธีการเพิ่มไปยังอึก
MrThunder

3

ฉันแก้ไขเพื่อ

test: {
        options: {
          port: 9000,
          base: [
            '.tmp',
            'test',
            '<%= yeoman.app %>'
          ],
         middleware: function (connect) {
                  return [
                      modRewrite(['^[^\\.]*$ /index.html [L]']),
                      connect.static('.tmp'),
                      connect().use(
                          '/bower_components',
                          connect.static('./bower_components')
                      ),
                      connect.static('app')
                  ];
              }
        }
      },

3

ฉันกำลังตอบคำถามนี้จากคำถามที่มีขนาดใหญ่กว่า:

เมื่อฉันเพิ่ม $ locationProvider.html5Mode (จริง) เว็บไซต์ของฉันจะไม่อนุญาตให้วาง URL ฉันจะกำหนดค่าเซิร์ฟเวอร์ของฉันให้ทำงานได้อย่างไรเมื่อ html5Mode เป็นจริง

เมื่อคุณเปิดใช้งาน html5Mode แล้วอักขระ # จะไม่ถูกใช้ใน URL ของคุณอีกต่อไป สัญลักษณ์ # มีประโยชน์เพราะไม่ต้องมีการกำหนดค่าฝั่งเซิร์ฟเวอร์ หากไม่มี # url จะดูดีกว่า แต่ก็ต้องมีการเขียนฝั่งเซิร์ฟเวอร์ซ้ำ นี่คือตัวอย่างบางส่วน:

สำหรับการเขียนซ้ำด่วนด้วย AngularJS คุณสามารถแก้ไขได้ด้วยการอัปเดตต่อไปนี้:

app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html'));
});

และ

<!-- FOR ANGULAR ROUTING -->
<base href="/">

และ

app.use('/',express.static(__dirname + '/public'));

ขอบคุณการแก้ปัญหา สำหรับ Nodejs เพิ่มไปยัง app.js ไปยัง app.use ('/ *', ดัชนี);
Tigin

2

ฉันเชื่อว่าปัญหาของคุณเกี่ยวกับเซิร์ฟเวอร์ เอกสารประกอบเชิงมุมเกี่ยวกับโหมด HTML5 (ที่ลิงก์ในคำถามของคุณ) ระบุว่า:

ฝั่งเซิร์ฟเวอร์การใช้โหมดนี้ต้องมีการเขียน URL ใหม่บนฝั่งเซิร์ฟเวอร์โดยทั่วไปคุณต้องเขียนลิงค์ทั้งหมดของคุณไปยังจุดเริ่มต้นของแอปพลิเคชันของคุณ (เช่น index.html)

ฉันเชื่อว่าคุณจะต้องตั้งค่า url rewrite ตั้งแต่ / ถึงถึง /


ขอบคุณสำหรับคำตอบ. ดังนั้นเมื่อฉันอยู่ในหน้าเกี่ยวกับและฉันรีเฟรชเซิร์ฟเวอร์ควรเขียน url เป็น /? ปัญหาคือฉันทำงานกับแบ็กเอนด์ทางรถไฟที่อยู่ในโดเมนอื่น การสื่อสารทั้งหมดเป็นการโทรผ่าน API ฉันจะเขียน URL เหล่านั้นใหม่ได้อย่างไร
Dieter De Mesmaeker

สิ่งที่เป็นแอปของคุณมีอยู่ที่เส้นทางเซิร์ฟเวอร์ของคุณ / ดังนั้นเมื่อคุณรีเฟรช URL ที่เป็น / เกี่ยวกับเบราว์เซอร์จะขอจากเซิร์ฟเวอร์ของคุณหน้าอะไรที่ / เกี่ยวกับ (ในกรณีนี้คุณไม่มีหน้ามีดังนั้นคุณต้องเปลี่ยนเส้นทาง หลังนั้น)
lucuma

2

เรามีเซิร์ฟเวอร์เปลี่ยนเส้นทางใน Express:

app.get('*', function(req, res){
    res.render('index');
});

<base href="https://stackoverflow.com/" />และเราก็ยังคงได้รับปัญหาหน้ารีเฟรชแม้หลังจากที่เราเพิ่ม

โซลูชัน: ตรวจสอบให้แน่ใจว่าคุณใช้ลิงก์จริงในหน้าเว็บของคุณเพื่อสำรวจ อย่าพิมพ์เส้นทางใน URL ไม่เช่นนั้นคุณจะได้รับการรีเฟรชหน้า ฉันรู้ผิด)

:-P


แต่เนื่องจากคำขอ http นี้ทุกคนจะมีไฟล์ดัชนีเช่น: / getJsonFromServer - คำขอ http ที่ส่งคืนข้อมูล แต่เนื่องจากการกำหนดค่านี้จะส่งคืนหน้าดัชนีด้วย
vijay

1

ในที่สุดฉันก็มีวิธีที่จะแก้ปัญหานี้โดยฝั่งเซิร์ฟเวอร์เพราะมันเหมือนกับปัญหาของ AngularJs เองฉันใช้ 1.5 Angularjs และฉันก็มีปัญหาเดียวกันในการโหลดหน้าซ้ำ แต่หลังจากเพิ่มโค้ดด้านล่างลงในserver.jsไฟล์ของฉันแล้วมันเป็นการประหยัดทั้งวันแต่มันก็ไม่ใช่ทางออกที่ดีหรือไม่ใช่วิธีที่ดี

app.use(function(req, res, next){
  var d = res.status(404);
     if(d){
        res.sendfile('index.html');
     }
});

0

ฉันพบปลั๊กอิน Grunt ที่ดียิ่งขึ้นซึ่งทำงานได้ถ้าคุณมี index.html และ Gruntfile.js ในไดเรกทอรีเดียวกัน

https://npmjs.org/package/grunt-connect-pushstate

หลังจากนั้นใน Gruntfile ของคุณ:

 var pushState = require('grunt-connect-pushstate/lib/utils').pushState;


    connect: {
    server: {
      options: {
        port: 1337,
        base: '',
        logger: 'dev',
        hostname: '*',
        open: true,
        middleware: function (connect, options) {
          return [
            // Rewrite requests to root so they may be handled by router
            pushState(),
            // Serve static files
            connect.static(options.base)
          ];
        }
      },
    }
},

โมดูล grunt-connect-pushstate เลิกใช้แล้ว
Evan Plaice

0
I solved same problem using modRewrite.  
AngularJS is reload page when after # changes.  
But HTML5 mode remove # and invalid the reload.  
So we should reload manually.
# install connect-modrewrite
    $ sudo npm install connect-modrewrite --save

# gulp/build.js
    'use strict';
    var gulp = require('gulp');
    var paths = gulp.paths;
    var util = require('util');
    var browserSync = require('browser-sync');
    var modRewrite  = require('connect-modrewrite');
    function browserSyncInit(baseDir, files, browser) {
        browser = browser === undefined ? 'default' : browser;
        var routes = null;
        if(baseDir === paths.src || (util.isArray(baseDir) && baseDir.indexOf(paths.src) !== -1)) {
            routes = {
                '/bower_components': 'bower_components'
            };
        }

        browserSync.instance = browserSync.init(files, {
            startPath: '/',
            server: {
            baseDir: baseDir,
            middleware: [
                modRewrite([
                    '!\\.\\w+$ /index.html [L]'
                ])
            ],
            routes: routes
            },
            browser: browser
        });
    }

0

ฉันมีปัญหาเดียวกันกับจาวา + app เชิงมุมสร้างขึ้นด้วยJHipster ฉันแก้ไขด้วยตัวกรองและรายการหน้าเชิงมุมทั้งหมดในคุณสมบัติ:

application.yml:

angular-pages:
  - login
  - settings
...

AngularPageReloadFilter.java

public class AngularPageReloadFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.getRequestDispatcher("index.html").forward(request, response);
    }
}

WebConfigurer.java

private void initAngularNonRootRedirectFilter(ServletContext servletContext,
                                              EnumSet<DispatcherType> disps) {
    log.debug("Registering angular page reload Filter");
    FilterRegistration.Dynamic angularRedirectFilter =
            servletContext.addFilter("angularPageReloadFilter",
                    new AngularPageReloadFilter());
    int index = 0;
    while (env.getProperty("angular-pages[" + index + "]") != null) {
        angularRedirectFilter.addMappingForUrlPatterns(disps, true, "/" + env.getProperty("angular-pages[" + index + "]"));
        index++;
    }
    angularRedirectFilter.setAsyncSupported(true);
}

หวังว่าจะเป็นประโยชน์สำหรับใครบางคน


0

อึก + เบราว์เซอร์ Sync:

ติดตั้ง connect-history-api-fallback ผ่านทาง npm หลังจากนั้นให้กำหนดค่างานบริการอึกของคุณ

var historyApiFallback = require('connect-history-api-fallback');

gulp.task('serve', function() {
  browserSync.init({
    proxy: {
            target: 'localhost:' + port,
            middleware: [ historyApiFallback() ]
        }
  });
});

0

รหัสฝั่งเซิร์ฟเวอร์ของคุณคือ JAVA จากนั้นทำตามขั้นตอนด้านล่าง

ขั้นตอนที่ 1: ดาวน์โหลด urlrewritefilter JAR คลิกที่นี่ และบันทึกเพื่อสร้างพา ธ WEB-INF / lib

ขั้นตอนที่ 2: เปิดใช้งานโหมด HTML5 $ locationProvider.html5Mode (จริง);

ขั้นตอนที่ 3: ตั้งค่า URL ฐาน <base href="https://stackoverflow.com/example.com/"/>

ขั้นตอนที่ 4: คัดลอกและวางไปที่ WEB.XML ของคุณ

 <filter>
     <filter-name>UrlRewriteFilter</filter-name>
 <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

ขั้นตอนที่ 5: สร้างไฟล์ใน WEN-INF / urlrewrite.xml

 <urlrewrite default-match-type="wildcard">


    <rule>
            <from>/</from>
            <to>/index.html</to>
        </rule>

    <!--Write every state dependent on your project url-->
    <rule>
            <from>/example</from>
            <to>/index.html</to>
        </rule>
    </urlrewrite>

วิธีเพิ่มกฎสำหรับ URL แบบไดนามิกเช่น - test.com/user/101 test.com/user/102
Krishna Kumar Chourasiya

0

ฉันมีวิธีแก้ปัญหาง่ายๆที่ฉันใช้และผลงาน

ในแอป / ข้อยกเว้น / Handler.php

เพิ่มที่ด้านบน:

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

จากนั้นภายในวิธีการเรนเดอร์

public function render($request, Exception $exception)
{
    .......

       if ($exception instanceof NotFoundHttpException){

        $segment = $request->segments();

        //eg. http://site.dev/member/profile
        //module => member
        // view => member.index
        //where member.index is the root of your angular app could be anything :)
        if(head($segment) != 'api' && $module = $segment[0]){
            return response(view("$module.index"), 404);
        }

        return response()->fail('not_found', $exception->getCode());

    }
    .......

     return parent::render($request, $exception);
}

0

ฉันได้แก้ไขปัญหาโดยการเพิ่มโค้ดด้านล่างลงในไฟล์ node.js

app.get("/*", function (request, response) {
    console.log('Unknown API called');
    response.redirect('/#' + request.url);
});

หมายเหตุ: เมื่อเรารีเฟรชหน้าเว็บจะค้นหา API แทนหน้าเชิงมุม (เนื่องจากไม่มีแท็ก # ใน URL) ใช้รหัสด้านบนฉันกำลังเปลี่ยนเส้นทางไปยัง URL ด้วย #


-2

เพียงแค่เขียนกฎใน web.config

<system.webServer>
  <rewrite>
    <rules>
    <rule name="AngularJS Routes" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
       </rules>
    </rewrite>
</system.webServer>

ในดัชนีเพิ่มสิ่งนี้

<base href="/">

มันใช้งานได้สำหรับฉันบางทีคุณอาจลืมตั้ง Html5Mode app.config

app.config(function ($stateProvider, $urlRouterProvider, $locationProvider){
    $locationProvider.html5Mode({ enabled: true, requireBase: true });
    $locationProvider.hashPrefix('!');
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.