首頁 web前端 js教程 Angular開發實踐之服務端渲染

Angular開發實踐之服務端渲染

May 28, 2018 pm 02:07 PM
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進行開發建構的,因此它們的差異只在於服務端渲染所需的那些配置上。
  1. 安裝工具

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

    即可):

    ######@angular/platform-server### - Universal 的服務端元件。 ###############@nguniversal/module-map-ngfactory-loader### - 用於處理服務端渲染環境下的惰性載入。 ###
  4. @nguniversal/express-engine - Universal 应用的 Express 引擎。

  5. ts-loader - 用于对服务端应用进行转译。

  6. 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 &#39;@angular/core&#39;;
import { ServerModule, ServerTransferStateModule } from &#39;@angular/platform-server&#39;;
import { ModuleMapLoaderModule } from &#39;@nguniversal/module-map-ngfactory-loader&#39;;

import { AppBrowserModule } from &#39;./app.module&#39;;
import { AppComponent } from &#39;./app.component&#39;;

// 可以注册那些在 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: &#39;my-app&#39;}),
    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) ? &#39;in the browser&#39; : &#39;on the server&#39;;
    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) ? &#39;in the browser&#39; : &#39;on the server&#39;;
  console.log(`Running ${platform} with appId=${appId}`);
}
登入後複製

3、创建服务端应用的引导程序文件:src/main.server.ts

该文件导出服务端模块:

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

4、修改客户端应用的引导程序文件:src/main.ts

监听 DOMContentLoaded 事件,在发生 DOMContentLoaded 事件时运行我们的代码,以使 TransferState 正常工作

import { enableProdMode } from &#39;@angular/core&#39;;
import { platformBrowserDynamic } from &#39;@angular/platform-browser-dynamic&#39;;

import { AppBrowserModule } from &#39;./app/app.module&#39;;
import { environment } from &#39;./environments/environment&#39;;

if (environment.production) {
  enableProdMode();
}

// 在 DOMContentLoaded 时运行我们的代码,以使 TransferState 正常工作
document.addEventListener(&#39;DOMContentLoaded&#39;, () => {
  platformBrowserDynamic().bootstrapModule(AppBrowserModule);
});
登入後複製

5、创建 TypeScript 的服务端配置:src/tsconfig.server.json

{
 "extends": "../tsconfig.json",
 "compilerOptions": {
  "outDir": "../out-tsc/app",
  "baseUrl": "./",
  "module": "commonjs",
  "types": [
   "node"
  ]
 },
 "exclude": [
  "test.ts",
  "**/*.spec.ts"
 ],
 "angularCompilerOptions": {
  "entryModule": "app/app.server.module#AppServerModule"
 }
}
登入後複製

tsconfig.app.json 的差异在于:

module 属性必须是 commonjs,这样它才能被 require() 方法导入你的服务端应用。

angularCompilerOptions 部分有一些面向 AOT 编译器的选项:

  1. 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 &#39;zone.js/dist/zone-node&#39;;
import &#39;reflect-metadata&#39;;
import { enableProdMode } from &#39;@angular/core&#39;;

import * as express from &#39;express&#39;;
import { join } from &#39;path&#39;;
import { readFileSync } from &#39;fs&#39;;

// 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(), &#39;dist&#39;);

// Our index.html we&#39;ll use as our template
const template = readFileSync(join(DIST_FOLDER, &#39;browser&#39;, &#39;index.html&#39;)).toString();

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require(&#39;./dist/server/main.bundle&#39;);

// Express Engine
import { ngExpressEngine } from &#39;@nguniversal/express-engine&#39;;
// Import module map for lazy loading
import { provideModuleMap } from &#39;@nguniversal/module-map-ngfactory-loader&#39;;

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(&#39;html&#39;, ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set(&#39;view engine&#39;, &#39;html&#39;);
app.set(&#39;views&#39;, join(DIST_FOLDER, &#39;browser&#39;));

/* - Example Express Rest API endpoints -
 app.get(&#39;/api/**&#39;, (req, res) => { });
*/

// Server static files from /browser
app.get(&#39;*.*&#39;, express.static(join(DIST_FOLDER, &#39;browser&#39;), {
  maxAge: &#39;1y&#39;
}));

// ALl regular routes use the Universal engine
app.get(&#39;*&#39;, (req, res) => {
  res.render(&#39;index&#39;, {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 &#39;zone.js/dist/zone-node&#39;;
import &#39;reflect-metadata&#39;;
import { readFileSync, writeFileSync, existsSync, mkdirSync } from &#39;fs&#39;;
import { join } from &#39;path&#39;;

import { enableProdMode } from &#39;@angular/core&#39;;
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Import module map for lazy loading
import { provideModuleMap } from &#39;@nguniversal/module-map-ngfactory-loader&#39;;
import { renderModuleFactory } from &#39;@angular/platform-server&#39;;
import { ROUTES } from &#39;./static.paths&#39;;

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require(&#39;./dist/server/main.bundle&#39;);

const BROWSER_FOLDER = join(process.cwd(), &#39;browser&#39;);

// Load the index.html file containing referances to your application bundle.
const index = readFileSync(join(&#39;browser&#39;, &#39;index.html&#39;), &#39;utf8&#39;);

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, &#39;index.html&#39;), 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(&#39;path&#39;);
const webpack = require(&#39;webpack&#39;);

module.exports = {
  entry: {
    server: &#39;./server.ts&#39;, // This is our Express server for Dynamic universal
    prerender: &#39;./prerender.ts&#39; // This is an example of Static prerendering (generative)
  },
  target: &#39;node&#39;,
  resolve: {extensions: [&#39;.ts&#39;, &#39;.js&#39;]},
  externals: [/(node_modules|main\..*\.js)/,], // Make sure we include all node_modules etc
  output: {
    path: path.join(__dirname, &#39;dist&#39;), // Puts the output at the root of the dist folder
    filename: &#39;[name].js&#39;
  },
  module: {
    rules: [
      {test: /\.ts$/, loader: &#39;ts-loader&#39;}
    ]
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/, // fixes WARNING Critical dependency: the request of a dependency is an expression
      path.join(__dirname, &#39;src&#39;), // 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, &#39;src&#39;),
      {}
    )
  ]
};
登入後複製

测试配置

通过上面的配置,我们就制作完成一个可在服务端渲染的 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 = [
  &#39;/&#39;,
  &#39;/lazy&#39;
];
登入後複製

因此,从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 &#39;@angular/core&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;
import { Observable } from &#39;rxjs/Observable&#39;;

@Component({
  selector: &#39;app-home&#39;,
  templateUrl: &#39;./home.component.html&#39;,
  styleUrls: [&#39;./home.component.scss&#39;]
})
export class HomeComponent implements OnInit, OnDestroy {
  constructor(public http: HttpClient) {
  }
  
  ngOnInit() {
    this.poiSearch(this.keyword, &#39;北京市&#39;).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 &#39;@angular/core&#39;;
import { makeStateKey, TransferState } from &#39;@angular/platform-browser&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;
import { Observable } from &#39;rxjs/Observable&#39;;

const KFCLIST_KEY = makeStateKey(&#39;kfcList&#39;);

@Component({
  selector: &#39;app-home&#39;,
  templateUrl: &#39;./home.component.html&#39;,
  styleUrls: [&#39;./home.component.scss&#39;]
})
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, &#39;北京市&#39;).subscribe((data: any) => {
        console.log(data);
        this.state.set(KFCLIST_KEY, data as any); // 存储数据
      });
    }
  }
  
  ngOnDestroy() {
    if (typeof window === &#39;object&#39;) {
      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 中根据当前是否客户端来决定是否将存储的数据进行删除

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Js面试算法详解

JS简单获取并修改input文本框内容的方法示例

详解vue表单

以上是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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 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)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
如何解決Windows中的「服務沒有回應」錯誤。 如何解決Windows中的「服務沒有回應」錯誤。 Apr 27, 2023 am 08:16 AM

NETSTART指令是Windows中的內建指令,可用於啟動和停止服務和其他程式。有時,在執行此命令時,您可能會遇到NetHelpmsg2186錯誤。遇到此錯誤的大多數用戶都試圖透過執行NETSTARTWUAUSERV命令來重新啟動Windows更新服務。如果Windows更新服務已停用或未執行,則您的系統可能會面臨風險,因為您無法取得最新更新。讓我們詳細探討為什麼會發生此錯誤以及如何繞過它。好嗎?什麼是錯誤2186? Windows更新服務透過安裝最新的關鍵更新和安全功

如何在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

win10安全中心服務已停用解決方案 win10安全中心服務已停用解決方案 Jul 16, 2023 pm 01:17 PM

安全中心服務是win10系統內建的電腦防護作用,能夠即時保護電腦安全,可是有些客戶在開機的時候碰見了安全中心服務被禁用的狀況,怎麼辦呢?很簡單,你可以打開服務面板,找到SecurityCenter項,以後右​​鍵打開它的屬性窗口,將啟動種類設定為自動,以後再點擊一下啟動就能夠再次開啟這個服務了。 win10安全中心服務被停用怎麼辦:1、按「Win+R」開啟「運作」視窗。 2.隨後輸入「services.msc」指令後按回車3、隨後在右邊視窗中找到「SecurityCenter」一項,並雙擊此項開啟其屬性窗

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

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

酷家樂怎麼渲染正交俯視圖_酷家樂渲染正交俯視圖教程 酷家樂怎麼渲染正交俯視圖_酷家樂渲染正交俯視圖教程 Apr 02, 2024 pm 01:10 PM

1.首先在酷家樂中開啟要渲染的設計方案。 2、然後在渲染選單下開啟俯視圖渲染。 3.接著在俯視圖渲染介面中點選參數設定中的正交。 4.最後調整好模型角度即可點選立即渲染,渲染正交俯視圖。

驗證碼攔不住機器人了!谷歌AI已能精準辨識模糊文字,GPT-4則裝瞎求人幫忙 驗證碼攔不住機器人了!谷歌AI已能精準辨識模糊文字,GPT-4則裝瞎求人幫忙 Apr 12, 2023 am 09:46 AM

「最煩登網站時各種奇奇怪怪(甚至變態)的驗證碼了。」現在,有一個好消息和一個壞消息。好消息就是:AI可以幫你代勞這件事了。不信你瞧,以下是三張辨識難度依序遞增的真實案例:而這些是一個名為「Pix2Struct」的模型給出的答案:全部準確無誤、一字不差有沒有?有網友感嘆:確定,準確度比我強。所以可不可以做成瀏覽器插件? ?不錯,有人表示:別看這幾個案例相比還算簡單,但凡微調一下,我都不敢想像其效果有多厲害了。所以,壞消息就是──驗證碼馬上就要攔不住機器人了! (危險危險危險…)如何做到? Pix2St

遠端桌面連線服務用指令開啟方法 遠端桌面連線服務用指令開啟方法 Dec 31, 2023 am 10:38 AM

遠端桌面連線為許多使用者的日常生活帶來了方便,也有部分想使用指令來進行遠端連接,操作起來更方便,那麼該怎麼連接呢?遠端桌面連線服務用指令開啟方法可以幫你解決。遠端桌面連線指令怎麼設定:方法一、透過執行指令遠端連線1、按下「Win+R」開啟「執行」輸入mstsc2、然後點選「顯示選項」3、輸入ip位址點選「連線」。 4、顯示正在連接即可。方法二、透過命令提示字元遠端連接1、按下「Win+R」開啟「執行」輸入cmd2、在「命令提示字元」輸入mstsc/v:192.168.1.250/console

Linux 重啟服務的正確方式是什麼? Linux 重啟服務的正確方式是什麼? Mar 15, 2024 am 09:09 AM

Linux重啟服務的正確方式是什麼?在使用Linux系統時,經常會遇到需要重新啟動某個服務的情況,但是有時我們可能會在重新啟動服務時遇到一些問題,例如服務沒有真正停止或啟動等情況。因此,掌握正確的重啟服務的方式是非常重要的。在Linux中,通常可以使用systemctl指令來管理系統服務。 systemctl指令是systemd系統管理員的一部分

See all articles