# Day?? 【牙起來】 - Angular 網頁部署設定
## Redirect Http to Https
使用Angular重新導向
以往需要透過伺服器IIS來做額外設定、或是Apache額外設定`.htaccess`檔案
省略了這些設定的功夫,這邊直接寫在程式裡,用js的方法把重新導向的邏輯做掉了
修改`app.component.ts`
```typescript=
import { Component, OnInit } from '@angular/core';
import { environment } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
title = 'website';
ngOnInit() {
if (location.protocol === 'http:') {
if (environment.production) {
window.location.href = location.href.replace('http', 'https');
}
}
}
}
```
其中必須做**是否為production環境**的判斷,否則在本地端 `ng serve` 時,預設網址是`http://localhost:4200/` 會一直導到https導致無法測試
這樣就可以都會導向到https囉
## 部署到伺服器上 Reload 404 問題
### 原理:
`ng build`之後,只會有這些檔案被部署上伺服器

瀏覽、加載SPA網頁首頁的時候沒問題,是因為伺服器有看到`index.html`,接著由Angular透過JS來掌管一切邏輯,按下其他頁面的按鈕時,透過Router導到其他網址`page2.html`,所有作動都是在Angular內部這包檔案中運作。
但當Refresh、Reload網頁重新載入的時候,伺服器沒有看到名為`page2.html`的檔案。
所以直接返回404,根本進入不到Angular掌管的那一步。
### 方法1 - 在伺服器端寫配置(不屬於Angular的部分)
從伺服器端出現的問題,由伺服器端寫邏輯導頁
網址維持`https://domain.com/page2.html`
又稱**Html5Mode**、**PathLocationStrategy**
### 方法2 - 在Angular加上useHash
又稱**HashMode**、**HashLocationStrategy**
> 名詞解釋
> Hash: `#`
> Hashbang: `#!`,AngularJS採用的模式
這個方法又有兩種做法
* 第一種做法:在`app-routing.module.ts`中加入`{useHash: true}`
```typescript=
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
```

* 第二種做法比較麻煩:用到了`provide`及`useClass`來覆寫
在`app.module.ts`中加入`providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],`,

Hashtag就是Fragment網址段落分段

缺點:網址會變成`https://domain.com/#/page2.html` 變醜變的奇怪
並且無法再使用`#`Fragment來跳到指定id位置
原理:雖然網址是`https://domain.com/#/page2.html`,但瀏覽器只會發送 `https://domain.com/`,使伺服器能依循到`index.html`檔案,對應到那包Angular檔案、而非找不到返回404,接下來的事情由Angular掌管。
```typescript=
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
bootstrap: [AppComponent],
})
export class AppModule {}
```
https://stackoverflow.com/questions/35284988/angular-2-404-error-occur-when-i-refresh-through-the-browser
https://nicolas.riousset.com/category/software-methodologies/fixing-angular-404-page-not-found-error-on-page-refresh/
### 方法3 - SSR prerender
TODO Angular Universal
https://medium.com/@dao.houssene/angular-the-hash-trap-b2d415c2c241
https://fullstackladder.dev/blog/2021/10/16/static-site-generator-using-angular-universal-prerender/
用了之後nodejs location undefined
https://stackoverflow.com/questions/70931014/location-is-not-defined-asp-net-zero-angular-universal
---
Angular 17以後則是在`app.config.ts`中加入以下
```
providers: [
provideRouter(routes, withHashLocation()),
],
```