Bộ định tuyến Angular 2.0 không hoạt động khi tải lại trình duyệt


189

Tôi đang sử dụng phiên bản Angular 2.0.0-alpha.30. Khi chuyển hướng đến một tuyến đường khác, sau đó làm mới trình duyệt, nó hiển thị Không thể GET / tuyến đường.

Bạn có thể giúp tôi tìm hiểu tại sao lỗi này xảy ra.



Cảm ơn đã trả lời nhưng một trong số đó là cho các phiên bản 1.x góc cạnh. Tôi đang đối mặt với vấn đề trong góc 2.0.
Vinz và Tonz 16/07/2015

1
Câu hỏi được liên kết là một vấn đề chung với PushState không phải là Angular cụ thể. Câu hỏi của bạn không cung cấp đủ thông tin để biết nếu nó có liên quan.
Günter Zöchbauer 16/07/2015

5
Angular 2.0 sử dụng bộ định tuyến hoàn toàn mới, vì vậy bài đăng được liên kết hiện không sử dụng được kể từ bộ định tuyến cũ
Vinz và Tonz 16/07/2015

Như tôi đã nói nếu đó là sự cố PushState thì nó không phải là cụ thể của Angular và không thể được sửa bởi Angular mà cần phải được sửa trên máy chủ.
Günter Zöchbauer 16/07/2015

Câu trả lời:


141

Lỗi bạn đang thấy là do bạn đang yêu cầu http: // localhost / tuyến không tồn tại. Theo Simon .

Khi sử dụng định tuyến html5, bạn cần ánh xạ tất cả các tuyến đường trong ứng dụng của mình (hiện là 404) sang index.html ở phía máy chủ của bạn. Dưới đây là một số tùy chọn cho bạn:

  1. sử dụng máy chủ trực tiếp: https://www.npmjs.com/package/live-server

    $live-server --entry-file=index.html`
    
  2. sử dụng nginx: http://nginx.org/en/docs/beginners_guide.html

    error_page 404 /index.html
    
  3. Tomcat - cấu hình của web.xml. Từ bình luận của Kunin

    <error-page>
          <error-code>404</error-code>
          <location>/index.html</location>
    </error-page>
    

1
Vì một người cần hỗ trợ phía máy chủ để định tuyến html5 nên nó hoạt động hoàn toàn tốt. Thanx
Prabhat

Tôi có thể sử dụng nginx làm proxy pub servekhông? Theo cách đó tôi không cần pub buildnhiều trong quá trình phát triển. Tôi đã cố gắng nhưng proxy_passkhông làm việc rất tốt với error_page.
Franklin Yu

@FranklinYu Tôi chưa từng làm điều đó trước đây. Bạn có giải quyết nó?
Quý Đường

1
Sử dụng nginx. , error_page 404 /index.html ở vị trí ứng dụng hoạt động với tôi. Cảm ơn bạn.
Richard K. Campion

2
Tomcat - cấu hình của web.xml <error-page> <error-code> 404 </ error-code> <location> /index.html </ location> </ error-page>
Một Kunin

65

Tuyên bố miễn trừ trách nhiệm: bản sửa lỗi này hoạt động với Alpha44

Tôi đã có cùng một vấn đề và giải quyết nó bằng cách triển khai HashLocationStrargety được liệt kê trong Angular.io API Preview.

https://angular.io/docs/ts/latest/api/common/index/HashLocationStrargety- class.html

Bắt đầu bằng cách nhập các chỉ thị cần thiết

import {provide} from 'angular2/angular2';
import {
  ROUTER_PROVIDERS,
  LocationStrategy,
  HashLocationStrategy
} from 'angular2/router';

Và cuối cùng, bootstrap tất cả cùng nhau như vậy

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
]);

Tuyến đường của bạn sẽ xuất hiện dưới dạng http: // localhost / # / tuyến và khi bạn làm mới, nó sẽ tải lại tại địa điểm thích hợp.

Mong rằng sẽ giúp!


1
mã này sẽ hoạt động tốt nhưng có một số Trình diễn trong kỹ thuật này bằng cách sử dụng mã này #sẽ thêm tính tự động trong URL. Có giải pháp nào để xóa # khỏi URL bằng cách sử dụng này không?
Pardeep Jain

Đồng ý, tôi đã thử triển khai "PathLocationStrargety" được liệt kê ở đây , nhưng không thể làm cho nó hoạt động được. Một URL mà không có #sẽ là tối ưu.
SimonHawgie

Có tôi cũng đã cố gắng tương tự với PathLocationStrategynhưng điều này không làm việc cho tôi. hoặc tôi đã sử dụng sai phương pháp hoặc tôi không biết cách sử dụng PathLocationStrargety.
Pardeep Jain

1
Điều này không làm việc cho tôi trong RC1. Nhập LocationStrargety, HashLocationStrargety từ '@ angular / router' không thành công.
tin

1
Xin lỗi vì đã quay lại câu hỏi này sau hơn 1 năm :) Nhưng HashLocationStrargety có giúp giữ nguyên đường dẫn Router không? Trong trường hợp của tôi khi tôi làm mới, nó sẽ đưa tôi đến localhost / # / < tuyến mặc định > tức là tuyến mặc định cho trang chủ. Làm cách nào để đi đến tuyến đường hiện tại mà tôi đã đi ban đầu khi tôi 'Làm mới'?
rajugaadu

47

Angular theo mặc định sử dụng Pushstate HTML5 ( PathLocationStrategytheo tiếng lóng Angular).
Bạn cần một máy chủ xử lý tất cả các yêu cầu như yêu cầu index.htmlhoặc bạn chuyển sang HashLocationStrategy(với # trong URL cho các tuyến đường) https://angular.io/docs/ts/latest/api/common/index/HashLocationStrargety- class. html

Xem thêm https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-USE-htaccess/

Để chuyển sang HashLocationStrategysử dụng

cập nhật cho> = RC.5 và 2.0.0 cuối cùng

import {HashLocationStrategy, LocationStrategy} from '@angular/common';

@NgModule({
  declarations: [AppCmp], 
  bootstrap: [AppCmp],
  imports: [BrowserModule, routes],
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
]);

hoặc ngắn hơn với useHash

imports: [RouterModule.forRoot(ROUTER_CONFIG, {useHash: true}), ...

đảm bảo bạn có tất cả hàng nhập khẩu theo yêu cầu

Đối với bộ định tuyến (RC.3) mới

<base href="."> 

cũng có thể gây ra 404.

Nó đòi hỏi thay thế

<base href="/">

cập nhật cho> = RC.x

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
  // or since RC.2
  {provide: LocationStrategy, useClass: HashLocationStrategy} 
]);

import {provide} from '@angular/core';
import {  
  PlatformLocation,  
  Location,  
  LocationStrategy,  
  HashLocationStrategy,  
  PathLocationStrategy,  
  APP_BASE_HREF}  
from '@angular/common';  

cập nhật cho> = beta.16 Nhập khẩu đã thay đổi

import {BrowserPlatformLocation} from '@angular/platform-browser';

import {provide} from 'angular2/core';
import {
  // PlatformLocation,
  // Location,
  LocationStrategy,
  HashLocationStrategy,
  // PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/router';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';

<beta.16

import {provide} from 'angular2/core';
import {
  HashLocationStrategy
  LocationStrategy,
  ROUTER_PROVIDERS,
} from 'angular2/router';

Xem thêm https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26 thay đổi đột phá


1
Cảm ơn! cung cấp dường như đã di chuyển dưới góc / lõi: nhập {cung cấp} từ 'angular2 / core'
StrangeLoop

1
Chỉ cần lưu ý: update for >= RC.x(RC.2) hoạt động với router 3.0.0-alpha.7, nhưng được providechú thích là không dùng nữa mà không có thông tin về chức năng nào thay thế nó.
Mrusful

Sử dụng{provide: SomeClass, useClass: OtherClass}
Günter Zöchbauer

2
Cập nhật câu trả lời nhiều nhất. Đối với phiên bản mới nhất của 2.4.1 góc cạnh, tôi đã có <base href = "./">. Thay đổi thành <base href = "/"> đã giải quyết vấn đề tôi gặp phải. Có thể hữu ích cho ai đó.
Saiyaff Farouk

28

Tôi nghĩ rằng lỗi bạn đang thấy là do bạn đang yêu cầu http: // localhost / tuyến không tồn tại. Bạn cần đảm bảo rằng máy chủ của bạn sẽ ánh xạ tất cả các yêu cầu đến trang index.html chính của bạn.

Vì Angular 2 sử dụng định tuyến html5 theo mặc định thay vì sử dụng băm ở cuối url, làm mới trang trông giống như một yêu cầu cho một tài nguyên khác.


7
Vậy làm thế nào để chúng ta sửa nó? Làm thế nào để chúng tôi ánh xạ tất cả các yêu cầu đến chỉ mục chính theo mặc định? nó có phụ thuộc vào máy chủ không?
Ayyash

1
Có, bạn sẽ làm điều này trên máy chủ với bất kỳ khung web nào bạn đang sử dụng. Cách khác là sử dụng HashLocationStrargety như được mô tả dưới đây.
Simon

Bạn sẽ tải lại SPA góc cạnh trong mọi tuyến đường không có mặt. Có phải nó nên được xử lý như thế nào?
Gary

Nó chỉ tải lại nếu người dùng nhấp vào làm mới trên trình duyệt, không phải khi người dùng thay đổi tuyến đường thông qua giao diện người dùng. Không thực sự có bất kỳ cách nào xung quanh tải lại khi người dùng làm mới.
Wallace Howery

19

Đây là tình huống phổ biến trong tất cả các phiên bản bộ định tuyến nếu bạn đang sử dụng chiến lược vị trí HTML mặc định.

Điều xảy ra là URL trên thanh trình duyệt là một url HTML đầy đủ bình thường, ví dụ như : http://localhost/route.

Vì vậy, khi chúng tôi nhấn Enter trong thanh trình duyệt, có một yêu cầu HTTP thực tế được gửi đến máy chủ để lấy một tệp có tên route.

Máy chủ không có tệp như vậy và không có thứ gì như express được cấu hình trên máy chủ để xử lý yêu cầu và cung cấp phản hồi, vì vậy máy chủ trả về 404 Không tìm thấy, vì không thể tìm thấy routetệp.

Những gì chúng tôi muốn là cho máy chủ trả lại index.htmltệp có chứa ứng dụng trang đơn. Sau đó, bộ định tuyến sẽ khởi động và xử lý /routeurl và hiển thị thành phần được ánh xạ tới nó.

Vì vậy, để khắc phục sự cố, chúng tôi cần định cấu hình máy chủ trả về index.html(giả sử đó là tên của tệp ứng dụng trang đơn của bạn) trong trường hợp không thể xử lý yêu cầu, trái với 404 Không tìm thấy.

Cách để làm điều này sẽ phụ thuộc vào công nghệ phía máy chủ đang được sử dụng. Nếu Java của nó chẳng hạn, bạn có thể phải viết một servlet, thì trong Rails, nó sẽ khác, v.v.

Để đưa ra một ví dụ cụ thể, ví dụ nếu bạn đang sử dụng NodeJ, bạn sẽ phải viết một phần mềm trung gian như thế này:

function sendSpaFileIfUnmatched(req,res) {
    res.sendFile("index.html", { root: '.' });
}

Và sau đó đăng ký nó ở cuối chuỗi trung gian:

app.use(sendSpaFileIfUnmatched);

Điều này sẽ phục vụ index.htmlthay vì trả lại 404, bộ định tuyến sẽ khởi động và mọi thứ sẽ hoạt động như mong đợi.


Đây chính xác là vấn đề của tôi. Nếu bạn sử dụng NGINX, câu trả lời này sẽ giúp giải quyết nó: stackoverflow.com/questions/7027636/iêu
Nathan

Có một hướng dẫn về cách làm điều này cho java? Cảm ơn.
000000000000000000000

13

Đảm bảo rằng phần này được đặt trong phần tử đầu của index.html:

<base href="https://stackoverflow.com/">

Các ví dụ trong Angular2 Routing & Navigation sử dụng tài liệu hướng dẫn đoạn mã sau vào đầu thay vì (họ giải thích tại sao trong ví dụ lưu ý trực tiếp của tài liệu):

<script>document.write('<base href="' + document.location + '" />');</script>

Khi bạn làm mới một trang, nó sẽ tự động đặt cơ sở href thành tài liệu hiện tại của bạn. Tôi có thể thấy điều này gây ra một số nhầm lẫn cho mọi người lướt qua tài liệu và cố gắng sao chép plunker.


Cảm ơn đã chia sẻ điều này. Hãy nói rõ hơn, nó chỉ hoạt động với tôi khi tôi đặt <base href = "/"> sau khi tải tất cả css trong <head> và trước khi tải các tệp ANY Js. Tôi hy vọng nó sẽ giúp được bất cứ ai
wmehanna

tôi có <base href = "./"> trong index.html rồi xóa '.' từ href và nó đã hoạt động ..
Saurabh Solanki

10

Nếu bạn muốn có thể nhập các url trong trình duyệt mà không cần định cấu hình Máy chủ ứng dụng của mình để xử lý tất cả các yêu cầu tới index.html, bạn phải sử dụng HashLocationStrargety .

Cách dễ nhất để cấu hình là sử dụng:

RouterModule.forRoot(routes, { useHash: true })

Thay vì:

RouterModule.forRoot(routes)

Với HashLocationStrargety các url của bạn sẽ giống như:

http://server:port/#/path

Cảm ơn! Điều này có ích, nhưng tôi không muốn #từ url, chúng ta có thể xóa cái này không?
Hidayt Rahman

7

Tôi gặp vấn đề tương tự với việc sử dụng webpack-dev-server. Tôi đã phải thêm tùy chọn devServer vào gói web của mình.

Giải pháp:

// in webpack
devServer: {
    historyApiFallback: true,
    stats: 'minimal'
}

Loại phép thuật voodoo: p Để biết thêm thông tin, hãy xem: webpack.github.io/docs/iêu
Jissay

7

Nếu bạn đang sử dụng Apache hoặc Nginx làm máy chủ, bạn phải tạo một .htaccess(nếu không được tạo trước đó) và "Bật" RewriteEngine

RewriteEngine On  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html

Không nhận được câu hỏi của bạn, phương pháp này đã được thử nghiệm trên máy chủ Apache và Nginx ( nginx.com )
Rakesh Roy

1
Điều này chỉ dành cho Apache; Định dạng cấu hình Nginx là hoàn toàn khác nhau.
Franklin Yu

5

Máy chủ của tôi là Apache, những gì tôi đã làm để sửa lỗi 404 khi làm mới hoặc liên kết sâu rất đơn giản. Chỉ cần thêm một dòng trong apache vhost config:

ErrorDocument 404 /index.html

Vì vậy, bất kỳ lỗi 404 nào cũng sẽ được chuyển hướng đến index.html, đây là điều mà định tuyến angular2 muốn.

Toàn bộ ví dụ về tập tin vhost:

<VirtualHost *:80>
  ServerName fenz.niwa.local
  DirectoryIndex index.html
  ErrorDocument 404 /index.html

  DocumentRoot "/Users/zhoum/Documents/workspace/fire/fire_service/dist"
  ErrorLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.error.log
  CustomLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.access.log combined

  <Directory "/Users/zhoum/Documents/workspace/fire/fire_service/dist">
    AllowOverride All
    Options Indexes FollowSymLinks
    #Order allow,deny
    #Allow from All
    Require all granted
  </Directory>

  Header set Access-Control-Allow-Origin "*"
  Header set Access-Control-Allow-Methods "GET, POST"
  Header set Access-Control-Allow-Credentials "true"
  Header set Access-Control-Allow-Headers "Accept-Encoding"
</VirtualHost>

Bất kể bạn đang sử dụng máy chủ nào, tôi nghĩ rằng toàn bộ vấn đề là tìm ra cách cấu hình máy chủ để chuyển hướng 404 đến index.html của bạn.


4

Cấu hình máy chủ không phải là một giải pháp cho một SPA là những gì tôi nghĩ. Bạn không muốn tải lại một SPA góc cạnh nếu một tuyến sai đi vào, phải không? Vì vậy, tôi sẽ không phụ thuộc vào tuyến máy chủ và chuyển hướng sang tuyến khác nhưng có, tôi sẽ để index.html xử lý tất cả các yêu cầu cho các tuyến đường góc của đường dẫn ứng dụng góc.

Hãy thử điều này thay vì các tuyến đường khác hoặc sai. Nó làm việc cho tôi, không chắc chắn nhưng có vẻ như công việc đang tiến triển. Tự vấp ngã điều này khi gặp phải một vấn đề.

@RouteConfig([
  { path: '/**', redirectTo: ['MycmpnameCmp'] }, 
   ...
  }
])

https://github.com/angular/angular/issues/4055

Tuy nhiên, hãy nhớ định cấu hình các thư mục máy chủ của bạn và truy cập ngay trong trường hợp bạn có các tập lệnh HTML hoặc web không phải là SPA. Khác, bạn sẽ phải đối mặt với các vấn đề. Đối với tôi khi gặp vấn đề như bạn, đó là sự pha trộn giữa cấu hình máy chủ và ở trên.


4

để sửa lỗi nhanh 5 góc, chỉnh sửa app.module.ts và thêm {useHash:true}sau appRoutes.

@NgModule(
{
  imports:[RouterModule.forRoot(appRoutes,{useHash:true})]
})

3

Các ứng dụng góc là ứng cử viên hoàn hảo để phục vụ với máy chủ HTML tĩnh đơn giản. Bạn không cần một công cụ phía máy chủ để tự động soạn các trang ứng dụng vì Angular thực hiện điều đó ở phía máy khách.

Nếu ứng dụng sử dụng bộ định tuyến Angular, bạn phải định cấu hình máy chủ để trả về trang chủ của ứng dụng (index.html) khi được yêu cầu một tệp mà nó không có.

Một ứng dụng định tuyến nên hỗ trợ "liên kết sâu". Liên kết sâu là một URL chỉ định đường dẫn đến một thành phần bên trong ứng dụng. Ví dụ: http://www.example.com/heroes/42 là một liên kết sâu đến trang chi tiết anh hùng hiển thị anh hùng với id: 42.

Không có vấn đề gì khi người dùng điều hướng đến URL đó từ bên trong một máy khách đang chạy. Bộ định tuyến Angular diễn giải URL và các tuyến đến trang đó và anh hùng.

Nhưng nhấp vào một liên kết trong email, nhập nó vào thanh địa chỉ trình duyệt hoặc chỉ làm mới trình duyệt trong khi trên trang chi tiết anh hùng - tất cả các hành động này đều được xử lý bởi chính trình duyệt, bên ngoài ứng dụng đang chạy. Trình duyệt đưa ra yêu cầu trực tiếp đến máy chủ cho URL đó, bỏ qua bộ định tuyến.

Một máy chủ tĩnh thường xuyên trả về index.html khi nhận được yêu cầu cho http://www.example.com/ . Nhưng nó từ chối http://www.example.com/heroes/42 và trả về 404 - Lỗi không tìm thấy trừ khi được định cấu hình để trả về index.html thay vào đó

Nếu sự cố này xảy ra trong sản xuất, hãy làm theo các bước dưới đây

1) Thêm tệp Web.Config trong thư mục src của ứng dụng góc của bạn. Đặt mã bên dưới trong đó.

<configuration>
<system.webServer>
<rewrite>
    <rules>
    <rule name="Angular Routes" 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>
</system.webServer>
</configuration>

2) Thêm một tham chiếu đến nó trong angular-cli.json. Trong angular-cli.json, đặt Web.config vào khối tài sản như bên dưới.

"assets": [
    "assets",
    "favicon.ico",
    "Web.config"
  ],

3) Bây giờ bạn có thể xây dựng giải pháp cho sản xuất bằng cách sử dụng

ng build --prod

Điều này sẽ tạo ra một thư mục dist. Các tập tin trong thư mục dist đã sẵn sàng để triển khai bởi bất kỳ chế độ nào.


Giải pháp tốt nhất, có thể tìm thấy các chi tiết từ angular: angular.io/guide/deployment#fallback Trong khi tạo tệp web.config đừng quên thêm thẻ <configure> </ configure>. Cảm ơn câu trả lời Malatesh.
Palash Roy

3

Bạn có thể sử dụng giải pháp này cho ứng dụng trung bình, tôi đã sử dụng ejs làm công cụ xem:

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(function (req, res, next) {
    return res.render('index.html');
});

và cũng được đặt trong angular-cli.json

"apps": [
    {
      "root": "src",
      "outDir": "views",

nó sẽ hoạt động tốt thay vì

app.get('*', function (req, res, next) {
    res.sendFile('dist/index.html', { root: __dirname });
 });

vấn đề tạo của nó với nhận các cuộc gọi db và trả về index.html


1
Điều này đã hoạt động hoàn hảo vào tháng 10 năm 2017 cho ứng dụng stack MEAN.
Đội ngũ Mindsect

2

Đối với những người trong chúng ta gặp khó khăn trong cuộc sống trong IIS: sử dụng mã PowerShell sau để khắc phục sự cố này dựa trên tài liệu Angular 2 chính thức (mà ai đó đã đăng trong chủ đề này? Http://blog.angular-university.io/angular2-router/ )

Import-WebAdministration
# Grab the 404 handler and update it to redirect to index.html.
$redirect = Get-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS 
$redirect.path = "/index.html"
$redirect.responseMode = 1
# shove the updated config back into IIS
Set-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS -value $redirect

Điều này chuyển hướng 404 đến tệp /index.html theo đề xuất trong tài liệu Angular 2 (liên kết ở trên).


2

Bạn có thể thử dưới đây. Nó làm việc cho tôi!

main.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

...
export class MainComponent implements OnInit {
    constructor(private router: Router) {
        let path: string = window.location.hash;
        if (path && path.length > 0) {
            this.router.navigate([path.substr(2)]);
        }
    }

    public ngOnInit() { }
}

Bạn có thể nâng cao hơn nữa path.substr (2) để phân chia thành các tham số của bộ định tuyến. Tôi đang sử dụng góc 2.4.9


Điều này thực sự hữu ích để xử lý làm mới trình duyệt! Đối với góc 5, tôi phải sửa đổi một chút để sử dụng window.location.pathname và so sánh giá trị đó với các đường dẫn dự kiến.
Wallace Howery

2

tôi chỉ cần thêm .htaccess trong root.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]
    RewriteRule ^ ./index.html
</IfModule>

Ở đây tôi chỉ cần thêm dấu chấm '.' (thư mục mẹ) trong /index.html vào ./index.html
đảm bảo tệp index.html của bạn trong đường dẫn cơ sở là đường dẫn thư mục chính và được đặt trong bản dựng dự án.


1

Tôi muốn duy trì đường dẫn URL của các trang phụ trong chế độ HTML5 mà không chuyển hướng trở lại chỉ mục và không có giải pháp nào ngoài đó cho tôi biết cách thực hiện điều này, vì vậy đây là cách tôi hoàn thành nó:

Tạo các thư mục ảo đơn giản trong IIS cho tất cả các tuyến đường của bạn và trỏ chúng vào thư mục gốc của ứng dụng.

Bao bọc system.webServer của bạn trong Web.config.xml bằng thẻ vị trí này, nếu không, bạn sẽ gặp lỗi trùng lặp từ việc tải Web.config lần thứ hai với thư mục ảo:

<configuration>
    <location path="." inheritInChildApplications="false">
    <system.webServer>
        <defaultDocument enabled="true">
            <files>
                <add value="index.html" />
            </files>
        </defaultDocument>
    </system.webServer>
  </location>
</configuration>

1

Tôi đã kiểm tra trong 2 hạt giống như thế nào nó hoạt động.

Bạn có thể sử dụng express-history-api-fallback để tự động chuyển hướng khi một trang được tải lại.

Tôi nghĩ đó là cách thanh lịch nhất để giải quyết vấn đề này IMO.


1

Nếu bạn muốn sử dụng PathLocationStrargety:

  • Cấu hình Wildfly:
    • Tạo tập tin undertow-handlers.conf được đặt trong WEB-INF
    • Nội dung: (loại trừ các điểm cuối còn lại của bạn!)
      • regex ['(. / tổng quan /?. ? $)'] chứ không phải regex ['(. / endpoint. )'] -> viết lại ['/ index.html']
      • regex ['(. / triển khai /?. ? $)'] chứ không phải regex ['(. / endpoint. )'] -> viết lại ['/ index.html']

Ứng dụng một trang với Java EE / Wildfly: cấu hình phía máy chủ


1

2017-Tháng Bảy-11: Vì điều này được liên kết từ một câu hỏi có vấn đề này nhưng sử dụng Angular 2 với Electron, tôi sẽ thêm giải pháp của mình vào đây.

Tất cả những gì tôi phải làm là xóa <base href="./">khỏi index.html của tôi và Electron bắt đầu tải lại trang thành công.


1

Thêm nhập khẩu:

import { HashLocationStrategy, LocationStrategy } from '@angular/common';

Và trong nhà cung cấp NgModule, thêm:

providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]

Trong chỉ mục chính.html Tệp của Ứng dụng thay đổi cơ sở href thành ./index.html từ/

Ứng dụng khi được triển khai trong bất kỳ máy chủ nào sẽ cung cấp một url thực sự cho trang có thể được truy cập từ bất kỳ ứng dụng bên ngoài nào.


1

Chỉ cần thêm .htaccess trong root đã giải quyết 404 trong khi làm mới trang ở góc 4 apache2.

<IfModule mod_rewrite.c>
    RewriteEngine on

    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]

    # Rewrite everything else to index.html
    # to allow html5 state links
    RewriteRule ^ index.html [L]
</IfModule>

1

Tôi nghĩ rằng bạn đang nhận được 404 vì bạn đang yêu cầu http: // localhost / tuyến không tồn tại trên máy chủ tomcat. Vì Angular 2 sử dụng định tuyến html 5 theo mặc định thay vì sử dụng băm ở cuối URL, làm mới trang trông giống như một yêu cầu cho một tài nguyên khác.

Khi sử dụng định tuyến góc trên tomcat, bạn cần đảm bảo rằng máy chủ của bạn sẽ ánh xạ tất cả các tuyến đường trong ứng dụng của bạn tới index.html chính trong khi làm mới trang. Có nhiều cách để giải quyết vấn đề này. Bất cứ ai phù hợp với bạn, bạn có thể đi cho điều đó.

1) Đặt mã bên dưới vào tệp web.xml của thư mục triển khai của bạn:

<error-page>
     <error-code>404</error-code>
     <location>/index.html</location>
</error-page>

2) Bạn cũng có thể thử sử dụng HashLocationStrargety với # trong URL cho các tuyến đường:

Hãy thử sử dụng:

RouterModule.forRoot (tuyến đường, {useHash: true})

Thay vì:

RouterModule.forRoot (tuyến đường)

Với HashLocationStrargety các url của bạn sẽ giống như:

http: // localhost / # / tuyến

3) Van viết lại URL Tomcat: Viết lại url bằng cách sử dụng cấu hình cấp máy chủ để chuyển hướng đến index.html nếu không tìm thấy tài nguyên.

3.1) Bên trong thư mục META-INF tạo một tệp ngữ cảnh và sao chép bối cảnh bên dưới nó.

<? xml version='1.0' encoding='utf-8'?>
<Context>
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

3.2) Bên trong WEB-INF, tạo tệp viết lại.config (tệp này chứa quy tắc Viết lại URL và được sử dụng bởi tomcat để viết lại URL). Bên trong viết lại.config, sao chép nội dung dưới đây:

  RewriteCond %{SERVLET_PATH} !-f
  RewriteRule ^/(.*)$ /index.html [L]

0

Đây không phải là câu trả lời đúng nhưng On-refresh bạn có thể chuyển hướng tất cả các cuộc gọi chết sang Trang chủ bằng cách hy sinh trang 404, đây là một bản hack tạm thời chỉ phát lại sau tệp 404.html

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
            window.location.href = "http://" + document.location.host;
        </script>
    </head>
</html>

0

Giải pháp tốt nhất để giải quyết "bộ định tuyến không hoạt động trên trình tải lại trình duyệt" là chúng ta nên sử dụng spa-back-back. Nếu bạn đang sử dụng ứng dụng angular2 với lõi asp.net thì chúng ta cần xác định nó trên trang "StartUp.cs". theo routs MVC. Tôi đang đính kèm mã.

 app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
            routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
        });

0

Câu trả lời là khá khó khăn. Nếu bạn sử dụng Máy chủ Apache (hoặc IIS) cũ đơn giản, bạn sẽ gặp sự cố vì các trang Angular không tồn tại thực sự. Chúng được "tính toán" từ tuyến đường Angular.

Có một số cách để khắc phục vấn đề. Một là sử dụng HashLocationStrargety được cung cấp bởi Angular. Nhưng một dấu hiệu sắc nét được thêm vào trong URL. Điều này chủ yếu là để tương thích với Angular 1 (tôi giả sử). Thực tế là phần sau phần sắc nét không phải là một phần của URL (sau đó máy chủ sẽ giải quyết phần đó trước dấu "#"). Điều đó có thể là hoàn hảo.

Đây là một phương pháp nâng cao (dựa trên thủ thuật 404). Tôi giả sử bạn có phiên bản "phân phối" của ứng dụng góc cạnh của mình (ng build --prod nếu bạn sử dụng Angular-CLI) và bạn truy cập các trang trực tiếp với máy chủ của mình và PHP được bật.

Nếu trang web của bạn dựa trên các trang (ví dụ Wordpress) và bạn chỉ có một thư mục dành riêng cho Angular (được đặt tên là "dist" trong ví dụ của tôi), bạn có thể làm điều gì đó kỳ lạ nhưng cuối cùng, đơn giản. Tôi giả sử bạn đã lưu trữ các trang Angular của mình trong "/ dist" (với theo <BASE HREF="/dist/">). Bây giờ sử dụng chuyển hướng 404 và sự trợ giúp của PHP.

Trong cấu hình Apache của bạn (hoặc trong .htaccesstệp của thư mục ứng dụng góc của bạn), bạn phải thêmErrorDocument 404 /404.php

404.php sẽ bắt đầu với mã sau:

<?php
$angular='/dist/';
if( substr($_SERVER['REQUEST_URI'], 0, strlen($angular)) == $angular ){
    $index = $_SERVER['DOCUMENT_ROOT'] . $angular . "index.html";
    http_response_code(200);
    include $index;
    die;
}

// NOT ANGULAR...
echo "<h1>Not found.</h1>"

trong đó $angulargiá trị được lưu trữ trong HREF của góc của bạn index.html.

Nguyên tắc khá đơn giản, nếu Apache không tìm thấy trang, chuyển hướng 404 được thực hiện cho tập lệnh PHP. Chúng tôi chỉ kiểm tra nếu trang nằm trong thư mục ứng dụng góc. Nếu đúng như vậy, chúng tôi chỉ cần tải index.html trực tiếp (không chuyển hướng): điều này là cần thiết để giữ cho URL không thay đổi. Chúng tôi cũng thay đổi mã HTTP từ 404 thành 200 (chỉ tốt hơn cho trình thu thập thông tin).

Nếu trang không tồn tại trong ứng dụng góc thì sao? Vâng, chúng tôi sử dụng "bắt tất cả" của bộ định tuyến góc (xem tài liệu về bộ định tuyến góc).

Phương pháp này hoạt động với một ứng dụng Angular nhúng bên trong một trang web cơ bản (tôi nghĩ nó sẽ là trường hợp trong tương lai).

GHI CHÚ:

  • Cố gắng làm tương tự với mod_redirect (bằng cách viết lại URL) hoàn toàn không phải là một giải pháp tốt vì các tệp (như tài sản) phải được tải thực sự thì sẽ nguy hiểm hơn nhiều so với chỉ sử dụng giải pháp "không tìm thấy".
  • Chỉ chuyển hướng bằng cách sử dụng ErrorDocument 404 /dist/index.htmlcác tác phẩm nhưng Apache vẫn phản hồi với mã lỗi 404 (điều này không tốt cho trình thu thập thông tin).

0

Đây không phải là bản sửa lỗi vĩnh viễn cho sự cố mà giống như cách khắc phục hoặc hack

Tôi đã gặp vấn đề tương tự khi triển khai Ứng dụng Angular của mình lên gh-page. Đầu tiên tôi được chào đón bằng tin nhắn 404 khi Làm mới các trang của mình trên gh-page.

Sau đó, như những gì @gunter chỉ ra tôi đã bắt đầu sử dụng HashLocationStrategyđược cung cấp với Angular 2.

Nhưng điều đó đi kèm với tập hợp các vấn đề của riêng nó, #trong url, nó thực sự tồi tệ khiến cho url trông tệ hơn như thế này https://rahulrsingh09.github.io/AngularConcepts/#/faq.

Tôi bắt đầu nghiên cứu về vấn đề này và tình cờ thấy một blog. Tôi đã thử cho nó một shot và nó hoạt động.

Đây là những gì tôi đã làm như được đề cập trong blog đó.

Bạn sẽ cần bắt đầu bằng cách thêm tệp 404.html vào repo trang gh của bạn có chứa tài liệu HTML trống bên trong - nhưng tài liệu của bạn phải có tổng số hơn 512 byte (được giải thích bên dưới). Tiếp theo đặt phần đánh dấu sau vào phần tử đầu trang 404.html của bạn:

<script>
  sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/REPO_NAME_HERE'"></meta>

Mã này đặt URL truy cập đã thử thành một biến trên đối tượng sessionStorage tiêu chuẩn và ngay lập tức chuyển hướng đến trang index.html của dự án của bạn bằng cách sử dụng thẻ làm mới meta. Nếu bạn đang làm trang web của Tổ chức Github, đừng đặt tên repo trong văn bản thay thế thuộc tính nội dung, chỉ cần làm điều này: content = "0; URL = '/'"

Để nắm bắt và khôi phục URL mà người dùng đã điều hướng ban đầu, bạn sẽ cần thêm thẻ tập lệnh sau vào đầu trang index.html trước khi có bất kỳ hành động JavaScript nào khác trên trạng thái hiện tại của trang:

<script>
  (function(){
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      history.replaceState(null, null, redirect);
    }
  })();
</script>

Bit JavaScript này truy xuất URL mà chúng tôi đã lưu trong sessionStorage trên trang 404.html và thay thế mục nhập lịch sử hiện tại bằng URL đó.

Tài liệu tham khảo Backalleycoder Cảm ơn @Daniel cho cách giải quyết này.

Bây giờ URL ở trên thay đổi thành https://rahulrsingh09.github.io/AngularCon accept / faq


0

Tôi đã sửa lỗi này (sử dụng phụ trợ Java / Spring) bằng cách thêm trình xử lý khớp với mọi thứ được xác định trong các tuyến Angular của tôi, gửi lại index.html thay vì 404. Điều này sau đó (lại) khởi động lại ứng dụng và tải đúng trang. Tôi cũng có một trình xử lý 404 cho bất cứ điều gì không bị bắt bởi điều này.

@Controller         ////don't use RestController or it will just send back the string "index.html"
public class Redirect {

    private static final Logger logger = LoggerFactory.getLogger(Redirect.class);

    @RequestMapping(value = {"comma", "sep", "list", "of", "routes"})
    public String redirectToIndex(HttpServletRequest request) {
        logger.warn("Redirect api called for URL {}. Sending index.html back instead. This will happen on a page refresh or reload when the page is on an Angular route", request.getRequestURL());
        return "/index.html";
    }
}

0

Nếu bạn đang sử dụng Apache hoặc Nginx làm máy chủ, bạn cần tạo .htaccess

<IfModule mime_module>
      AddHandler application/x-httpd-ea-php72 .php .php7 .phtml
    </IfModule>
    # php -- END cPanel-generated handler, do not edit

    <IfModule mod_rewrite.c>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html
        # to allow html5 state links
        RewriteRule ^ index.html [L]
    </IfModule>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.