首頁 web前端 js教程 Angular給服務端渲染實戰案例

Angular給服務端渲染實戰案例

May 08, 2018 am 09:55 AM
angular 實戰 案例

這次帶給大家Angular給服務端渲染實戰案例,Angular給服務端渲染的注意事項有哪些,下面就是實戰案例,一起來看一下。

Angular Universal

Angular在服務端渲染方面提供一套前後端同構解決方案,它就是Angular Universal(統一平台),一項在服務端運行Angular 應用的技術。

標準的 Angular 應用程式會執行在瀏覽器中,它會在 DOM 中渲染頁面,以回應使用者的操作。

而 Angular Universal 會在服務端透過一個被稱為服務端渲染(server-side rendering - SSR)的過程產生靜態的應用頁面。

它可以產生這些頁面,並在瀏覽器請求時直接用它們給予回應。它也可以把頁面預先先生變成 HTML 文件,然後把它們當作靜態文件供伺服器使用。

工作原理

要製作一個 Universal 應用,就要安裝 platform-server 套件。 platform-server 套件提供了服務端的 DOM 實作、XMLHttpRequest 和其它底層特性,但不再依賴瀏覽器。

你要使用 platform-server 模組而不是 platform-b​​rowser 模組來編譯這個客戶端應用,並且在一個 Web 伺服器上執行這個 Universal 應用程式。

伺服器(下面的範例中使用的是 Node Express 伺服器)會把客戶端對應用程式頁面的請求傳給 renderModuleFactory 函數。

renderModuleFactory 函數接受一個模板 HTML 頁面(通常是 index.html)、一個包含元件的 Angular 模組和一個用於決定該顯示哪些元件的路由作為輸入。

該路由從客戶端的請求中傳給伺服器。每次請求都會給出所請求路由的一個適當的視圖。

renderModuleFactory 在範本中的 <app> 標籤中渲染出哪個視圖,並為客戶端建立一個完成的 HTML 頁面。

最後,伺服器就會把渲染好的頁面回傳給客戶端。

為什麼要服務端渲染

三個主要原因:

  1. 幫助網路爬蟲(SEO)

  2. 提昇在手機和低功耗設備上的效能

  3. 快速顯示出第一個頁面

##幫助網路爬蟲(SEO)

Google、Bing、百度、Facebook、Twitter 和其它搜尋引擎或社群媒體網站都依賴網路爬蟲來索引你的應用程式內容,並且讓它的內容可以透過網路搜尋。

這些網路爬蟲可能不會像人類那樣導航到你的具有高度互動性的 Angular 應用,並為其建立索引。

Angular Universal 可以為你產生應用的靜態版本,它易搜尋、可鏈接,瀏覽時也不必借助 JavaScript。它也讓網站可以被預覽,因為每個 URL 返回的都是一個完全渲染好的頁面。 啟用網路爬蟲通常被稱為搜尋引擎最佳化 (SEO)。

提昇手機和低功耗裝置上的效能

有些裝置不支援 JavaScript 或 JavaScript 執行得很差,導致使用者體驗不可接受。對於這些情況,你可能需要該應用程式的服務端渲染、無 JavaScript 的版本。雖然有一些限制,不過這個版本可能是那些完全沒辦法使用該應用程式的人的唯一選擇。

######快速顯示首頁#########快速顯示首頁對於吸引使用者是至關重要的。 ######如果頁面載入超過了三秒鐘中,那麼 53% 的行動網站會被放棄。你的應用程式需要啟動的更快一點,以便在用戶決定做別的事情之前吸引他們的注意力。 ######使用 Angular Universal,你可以為應用程式產生“著陸頁”,它們看起來就和完整的應用程式一樣。這些著陸頁是純 HTML,並且即使 JavaScript 被禁用了也能顯示。這些頁面不會處理瀏覽器事件,不過它們可以用 routerLink 在這個網站中導航。 ###

在實務中,你可能要使用一個登陸頁的靜態版本來保持使用者的注意力。同時,你也會在幕後載入完整的 Angular 應用程式。使用者會認為著陸頁幾乎是立即出現的,而當完整的應用程式載入完畢後,又可以獲得完全的互動體驗。

範例解析

下面將基於我在GitHub上的範例專案 angular-universal-starter 來進行解說。

這個專案與第一篇的範例專案一樣,都是基於 Angular CLI進行開發建構的,因此它們的差異只在於服務端渲染所需的那些配置上。

安裝工具

在開始之前,下列套件是必須安裝的(範例項目都已配置好,只需npm install 即可):

  1. @angular/platform-server - Universal 的服務端元件。

  2. @nguniversal/module-map-ngfactory-loader - 用於處理服務端渲染環境下的惰性載入。

  3. @nguniversal/express-engine - Universal 應用的 Express 引擎。

  4. ts-loader - 用於對服務端應用進行轉譯。

  5. express - Node Express 伺服器

#使用下列指令安裝它們:

npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine express
登入後複製

專案配置

設定工作有:

  1. 建立服務端應用程式模組:src/app/app.server.module.ts

  2. # #修改客戶端應用程式模組:src/app/app.module.ts

  3. 建立服務端應用程式的引導程式檔案:src/main.server.ts

  4. 修改客戶端應用程式的引導程式檔案:src/main.ts

  5. #建立TypeScript 的服務端設定:src/tsconfig.server.json

  6. #修改@angular/cli 的

    設定檔:.angular-cli.json

  7. 建立Node Express 的服務程式:server. ts

  8. 建立服務端預先渲染的程式:prerender.ts

  9. #建立Webpack 的服務端設定:webpack.server.config.js

1、建立服務端應用程式模組:

src/app/app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppBrowserModule } from './app.module';
import { AppComponent } from './app.component';
// 可以注册那些在 Universal 环境下运行应用时特有的服务提供商
@NgModule({
  imports: [
    AppBrowserModule, // 客户端应用的 AppModule
    ServerModule, // 服务端的 Angular 模块
    ModuleMapLoaderModule, // 用于实现服务端的路由的惰性加载
    ServerTransferStateModule, // 在服务端导入,用于实现将状态从服务器传输到客户端
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {
}
登入後複製
服務端應用程式模組(習慣上稱為AppServerModule)是一個Angular 模組,它包裝了應用的根模組AppModule,以便Universal 可以在你的應用程式和伺服器之間進行協調。 AppServerModule 也會告訴 Angular 再把你的應用程式以 Universal 方式運作時,該如何引導它。

2、修改客戶端應用程式模組:

src/app/app.module.ts#

@NgModule({
  imports: [
    AppRoutingModule,
    BrowserModule.withServerTransition({appId: 'my-app'}),
    TransferHttpCacheModule, // 用于实现服务器到客户端的请求传输缓存,防止客户端重复请求服务端已完成的请求
    BrowserTransferStateModule, // 在客户端导入,用于实现将状态从服务器传输到客户端
    HttpClientModule
  ],
  declarations: [
    AppComponent,
    HomeComponent
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppBrowserModule {
  constructor(@Inject(PLATFORM_ID) private platformId: Object,
        @Inject(APP_ID) private appId: string) {
    
    // 判断运行环境为客户端还是服务端
    const platform = isPlatformBrowser(platformId) ? 'in the browser' : 'on the server';
    console.log(`Running ${platform} with appId=${appId}`);
  }
}
登入後複製

NgModule 的元資料中BrowserModule 的導入改成BrowserModule.withServerTransition({appId: 'my-app'}),Angular 會把appId 值(它可以是任何字串)加入到服務端渲染頁面的樣式名中,以便它們在客戶端應用程式啟動時可以被找到並移除。

此時,我們可以透過

依賴注入@Inject(PLATFORM_ID)@Inject(APP_ID))來取得關於目前平台和appId 的執行時間資訊:

constructor(@Inject(PLATFORM_ID) private platformId: Object,
      @Inject(APP_ID) private appId: string) {
  
  // 判断运行环境为客户端还是服务端
  const platform = isPlatformBrowser(platformId) ? 'in the browser' : 'on the server';
  console.log(`Running ${platform} with appId=${appId}`);
}
登入後複製
3、建立服務端應用程式的引導程式檔案:

src/main.server.ts##該檔案匯出服務端模組:

export { AppServerModule } from './app/app.server.module';
登入後複製

4、修改客戶端應用程式的引導程式檔案:

src/main.ts

監聽DOMContentLoaded 事件,在發生DOMContentLoaded 事件時執行我們的程式碼,以讓TransferState 正常運作

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppBrowserModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
  enableProdMode();
}
// 在 DOMContentLoaded 时运行我们的代码,以使 TransferState 正常工作
document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppBrowserModule);
});
登入後複製

5、建立TypeScript 的服務端設定:

src/tsconfig.server.json

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">{  &quot;extends&quot;: &quot;../tsconfig.json&quot;,  &quot;compilerOptions&quot;: {   &quot;outDir&quot;: &quot;../out-tsc/app&quot;,   &quot;baseUrl&quot;: &quot;./&quot;,   &quot;module&quot;: &quot;commonjs&quot;,   &quot;types&quot;: [    &quot;node&quot;   ]  },  &quot;exclude&quot;: [   &quot;test.ts&quot;,   &quot;**/*.spec.ts&quot;  ],  &quot;angularCompilerOptions&quot;: {   &quot;entryModule&quot;: &quot;app/app.server.module#AppServerModule&quot;  } }</pre><div class="contentsignin">登入後複製</div></div>

tsconfig.app.json

的差異在於:module 屬性必須是commonjs,這樣它才能被require() 方法匯入你的服務端套用。

angularCompilerOptions 部分有一些面向 AOT 編譯器的選項:

    entryModule - 服務端應用的根模組,其格式為 path/to/file#ClassName。

6、修改 @angular/cli 的配置文件:.angular-cli.json

apps 下添加:

{
  "platform": "server",
  "root": "src",
  "outDir": "dist/server",
  "assets": [
   "assets",
   "favicon.ico"
  ],
  "index": "index.html",
  "main": "main.server.ts",
  "test": "test.ts",
  "tsconfig": "tsconfig.server.json",
  "testTsconfig": "tsconfig.spec.json",
  "prefix": "",
  "styles": [
   "styles.scss"
  ],
  "scripts": [],
  "environmentSource": "environments/environment.ts",
  "environments": {
   "dev": "environments/environment.ts",
   "prod": "environments/environment.prod.ts"
  }
}
登入後複製

7、创建 Node Express 的服务程序:server.ts

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');
// Our index.html we'll use as our template
const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main.bundle');
// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
/* - Example Express Rest API endpoints -
 app.get('/api/**', (req, res) => { });
*/
// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), {
  maxAge: '1y'
}));
// ALl regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', {req});
});
// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});
登入後複製

8、创建服务端预渲染的程序:prerender.ts

// Load zone.js for the server.
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
import { enableProdMode } from '@angular/core';
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { renderModuleFactory } from '@angular/platform-server';
import { ROUTES } from './static.paths';
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main.bundle');
const BROWSER_FOLDER = join(process.cwd(), 'browser');
// Load the index.html file containing referances to your application bundle.
const index = readFileSync(join('browser', 'index.html'), 'utf8');
let previousRender = Promise.resolve();
// Iterate each route path
ROUTES.forEach(route => {
  const fullPath = join(BROWSER_FOLDER, route);
  // Make sure the directory structure is there
  if (!existsSync(fullPath)) {
    mkdirSync(fullPath);
  }
  // Writes rendered HTML to index.html, replacing the file if it already exists.
  previousRender = previousRender.then(_ => renderModuleFactory(AppServerModuleNgFactory, {
    document: index,
    url: route,
    extraProviders: [
      provideModuleMap(LAZY_MODULE_MAP)
    ]
  })).then(html => writeFileSync(join(fullPath, 'index.html'), html));
});
登入後複製

9、创建 Webpack 的服务端配置:webpack.server.config.js

Universal 应用不需要任何额外的 Webpack 配置,Angular CLI 会帮我们处理它们。但是由于本例子的 Node Express 的服务程序是 TypeScript 应用(server.ts及prerender.ts),所以要使用 Webpack 来转译它。这里不讨论 Webpack 的配置,需要了解的移步 Webpack官网

// Work around for https://github.com/angular/angular-cli/issues/7200
const path = require('path');
const webpack = require('webpack');
module.exports = {
  entry: {
    server: './server.ts', // This is our Express server for Dynamic universal
    prerender: './prerender.ts' // This is an example of Static prerendering (generative)
  },
  target: 'node',
  resolve: {extensions: ['.ts', '.js']},
  externals: [/(node_modules|main\..*\.js)/,], // Make sure we include all node_modules etc
  output: {
    path: path.join(dirname, 'dist'), // Puts the output at the root of the dist folder
    filename: '[name].js'
  },
  module: {
    rules: [
      {test: /\.ts$/, loader: 'ts-loader'}
    ]
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/, // fixes WARNING Critical dependency: the request of a dependency is an expression
      path.join(dirname, 'src'), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      /(.+)?express(\\|\/)(.+)?/, // fixes WARNING Critical dependency: the request of a dependency is an expression
      path.join(dirname, 'src'),
      {}
    )
  ]
};
登入後複製

测试配置

通过上面的配置,我们就制作完成一个可在服务端渲染的 Angular Universal 应用。

在 package.json 的 scripts 区配置 build 和 serve 有关的命令:

{
  "scripts": {
    "ng": "ng",
    "start": "ng serve -o",
    "ssr": "npm run build:ssr && npm run serve:ssr",
    "prerender": "npm run build:prerender && npm run serve:prerender",
    "build": "ng build",
    "build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
    "build:prerender": "npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:prerender",
    "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
    "generate:prerender": "cd dist && node prerender",
    "webpack:server": "webpack --config webpack.server.config.js --progress --colors",
    "serve:prerender": "cd dist/browser && http-server",
    "serve:ssr": "node dist/server"
  }
}
登入後複製

开发只需运行 npm run start执行 npm run ssr 编译应用程序,并启动一个Node Express来为应用程序提供服务 http://localhost:4000

dist目录:

执行npm run prerender - 编译应用程序并预渲染应用程序文件,启动一个演示http服务器,以便您可以查看它 http://localhost:8080

注意: 要将静态网站部署到静态托管平台,您必须部署dist/browser文件夹, 而不是dist文件夹

dist目录:

根据项目实际的路由信息并在根目录的 static.paths.ts 中配置,提供给 prerender.ts 解析使用。

export const ROUTES = [
  '/',
  '/lazy'
];
登入後複製

因此,从dist目录可以看到,服务端预渲染会根据配置好的路由在 browser 生成对应的静态index.html。如 / 对应 /index.html/lazy 对应 /lazy/index.html

服务器到客户端的状态传输

在前面的介绍中,我们在 app.server.module.ts 中导入了 ServerTransferStateModule,在 app.module.ts 中导入了 BrowserTransferStateModuleTransferHttpCacheModule

这三个模块都与服务器到客户端的状态传输有关:

  1. ServerTransferStateModule:在服务端导入,用于实现将状态从服务器传输到客户端

  2. BrowserTransferStateModule:在客户端导入,用于实现将状态从服务器传输到客户端

  3. TransferHttpCacheModule:用于实现服务器到客户端的请求传输缓存,防止客户端重复请求服务端已完成的请求

使用这几个模块,可以解决 http请求在服务端和客户端分别请求一次 的问题。

比如在 home.component.ts 中有如下代码:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnDestroy {
  constructor(public http: HttpClient) {
  }
  
  ngOnInit() {
    this.poiSearch(this.keyword, '北京市').subscribe((data: any) => {
      console.log(data);
    });
  }
  
  ngOnDestroy() {
  }
  
  poiSearch(text: string, city?: string): Observable<any> {
    return this.http.get(encodeURI(`http://restapi.amap.com/v3/place/text?keywords=${text}&city=${city}&offset=20&key=55f909211b9950837fba2c71d0488db9&extensions=all`));
  }
}
登入後複製

代码运行之后,

服务端请求并打印:

客户端再一次请求并打印:

方法1:使用 TransferHttpCacheModule

使用 TransferHttpCacheModule 很简单,代码不需要改动。在 app.module.ts 中导入之后,Angular自动会将服务端请求缓存到客户端,换句话说就是服务端请求到数据会自动传输到客户端,客户端接收到数据之后就不会再发送请求了。

方法2:使用 BrowserTransferStateModule

该方法稍微复杂一些,需要改动一些代码。

调整 home.component.ts 代码如下:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { makeStateKey, TransferState } from '@angular/platform-browser';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
const KFCLIST_KEY = makeStateKey('kfcList');
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnDestroy {
  constructor(public http: HttpClient,
        private state: TransferState) {
  }
  
  ngOnInit() {
  
    // 采用一个标记来区分服务端是否已经拿到了数据,如果没拿到数据就在客户端请求,如果已经拿到数据就不发请求
    const kfcList:any[] = this.state.get(KFCLIST_KEY, null as any);
    if (!this.kfcList) {
      this.poiSearch(this.keyword, '北京市').subscribe((data: any) => {
        console.log(data);
        this.state.set(KFCLIST_KEY, data as any); // 存储数据
      });
    }
  }
  
  ngOnDestroy() {
    if (typeof window === 'object') {
      this.state.set(KFCLIST_KEY, null as any); // 删除数据
    }
  }
  
  poiSearch(text: string, city?: string): Observable<any> {
    return this.http.get(encodeURI(`http://restapi.amap.com/v3/place/text?keywords=${text}&city=${city}&offset=20&key=55f909211b9950837fba2c71d0488db9&extensions=all`));
  }
}
登入後複製
  1. 使用 const KFCLIST_KEY = makeStateKey('kfcList') 创建储存传输数据的 StateKey

  2. HomeComponent构造函数中注入 TransferState

  3. ngOnInit 中根据 this.state.get(KFCLIST_KEY, null as any) 判断数据是否存在(不管是服务端还是客户端),存在就不再请求,不存在则请求数据并通过 this.state.set(KFCLIST_KEY, data as any) 存储传输数据

  4. ngOnDestroy 中根据当前是否客户端来决定是否将存储的数据进行删除

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

vue做出全选与反选功能

vue.js element-ui tree树形控件如何修改iview

以上是Angular給服務端渲染實戰案例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在Ubuntu 24.04上安裝Angular 如何在Ubuntu 24.04上安裝Angular Mar 23, 2024 pm 12:20 PM

Angular.js是一種可自由存取的JavaScript平台,用於建立動態應用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應用程式的各個方面。 Angular.js提供了一系列工具,可協助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環境,可讓您在伺服器端執行JavaScript程式碼。要在Ub

一文探究Angular中的服務端渲染(SSR) 一文探究Angular中的服務端渲染(SSR) Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 嗎?可以幫助網站提供更好的 SEO 支援哦!

如何使用PHP和Angular進行前端開發 如何使用PHP和Angular進行前端開發 May 11, 2023 pm 04:04 PM

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

PHP實戰:快速實作斐波那契數列的程式碼範例 PHP實戰:快速實作斐波那契數列的程式碼範例 Mar 20, 2024 pm 02:24 PM

PHP實戰:快速實現斐波那契數列的程式碼範例斐波那契數列是數學中一個非常有趣且常見的數列,其定義如下:第一個和第二個數為0和1,從第三個數開始,每個數都是前兩個數的和。斐波那契數列的前幾個數字依序為0,1,1.2,3,5,8,13,21,...依此類推。在PHP中,我們可以透過遞歸和迭代兩種方式來實現斐波那契數列的生成。下面我們分別來展示這兩

Angular元件及其顯示屬性:了解非block預設值 Angular元件及其顯示屬性:了解非block預設值 Mar 15, 2024 pm 04:51 PM

Angular框架中元件的預設顯示行為不是區塊級元素。這種設計選擇促進了元件樣式的封裝,並鼓勵開發人員有意識地定義每個元件的顯示方式。透過明確設定CSS屬性 display,Angular組件的顯示可以完全控制,從而實現所需的佈局和響應能力。

一文詳解Angular父子組件間傳資料的方法 一文詳解Angular父子組件間傳資料的方法 Jan 04, 2023 pm 09:06 PM

這篇文章帶大家了解Angular父子元件(Component)之間傳遞資料的方法,介紹一下Angular中父元件向子元件傳資料、子元件傳送資料給父元件的方法,希望對大家有幫助!

使用Angular和Node進行基於令牌的身份驗證 使用Angular和Node進行基於令牌的身份驗證 Sep 01, 2023 pm 02:01 PM

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受

Java開發實戰:整合七牛雲雲端儲存服務實作文件上傳 Java開發實戰:整合七牛雲雲端儲存服務實作文件上傳 Jul 06, 2023 pm 06:22 PM

Java開發實戰:整合七牛雲端儲存服務實作檔案上傳引言隨著雲端運算和雲端儲存的發展,越來越多的應用程式需要將檔案上傳至雲端進行儲存和管理。雲端儲存服務的優勢在於高可靠性、可擴充性和靈活性。本文將介紹如何使用Java語言開發,整合七牛雲端儲存服務,實現文件上傳功能。七牛雲簡介七牛雲是國內領先的雲端儲存服務供應商,提供了全面的雲端儲存和內容分發服務。使用者可以透過七牛雲提

See all articles