.Net Core Web Api_筆記26_使用Angular搭配進行API存取開發(同源政策設定)

 


新建好一個.net 5 web api專案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AngularWebApiApp.Models
{
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Sex { get; set; }
    }
}



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using AngularWebApiApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AngularWebApiApp.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        [HttpGet("GetStudents")]
        public List<Student> GetStudents()
        {
            return new List<Student>()
            {
                new Student() {Id=1,Name="Jack",Age=23,Sex="male"},
                new Student() {Id=2,Name="Sandy",Age=25,Sex="female"},
                new Student() {Id=3,Name="Janet",Age=21,Sex="female"}
            };
        }

        [HttpPost("AddStudent")]
        public string AddStudent(Student student)
        {
            string result = "";
            if (student != null)
            {
                var stu_id = student.Id.ToString();
                var stu_name = student.Name;
                var stu_age = student.Age.ToString();
                var stu_sex = student.Sex;
                result = "success";
            }            
            return result;
        }


    }
}


開發電腦作業系統環境也確認已經裝好
NodeJs , NPM 以及Angular Cli


cmd 切換目錄到.net core web api 專案所在folder






就Browser而言有所謂的同源政策
白話來說也就是同一個網站內的程式資源可互相存取訪問,但若不同則禁止訪問。

比方不同domain name
http://abc.com跟http://def.com
或同domain name但不同port的
http://localhost:3500 跟 http://localhost:3800 
皆為非同源的實際案例


對Angular cli另外建構出的一個web應用會別於原本的.net core WebApi應用
兩個會在不同源(不同站台屬於兩個不同的各自獨立網站應用)
因此預設是無法直接互相存取的

一個是屬於Server-Side 的 .net core WebAPI
一個是屬於Client-Side 的 Angular


在此需要將Server-Side允許跨域機制給開啟
因此可至Startup.cs中的ConfigureServices註冊AddCors的服務配置
允許跨域

還要到Configure去加入Cors的middleware


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AngularWebApiApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("any", builder =>
                 {
                     //允許任何不同來源的站台應用存取
                     builder.SetIsOriginAllowed(_ => true)
                     .AllowAnyMethod()
                     .AllowAnyHeader()
                     .AllowCredentials();
                 });
            });
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors("any");//必須要在app.UseRouting();之後,app.UseAuthorization();跟app.UseEndpoints之前
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}




至~/AngularApp/src下新增一個folder取名mycomponents



新增一個component的ts程式檔,在此暫時先只實作Get請求的http呼叫。
student.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: '<button id="input" (click)="getData()">獲得資料</button>'
})

export class AppComponent {
  constructor(private http: HttpClient) { }
  url: string = 'http://localhost:15950/api/student/GetStudents';
  getData() {
    this.http.get(this.url).subscribe(function (result) {
      console.log(result);
    });
  }
}




新增一個module的ts程式檔
student.module.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './student.component';

@NgModule({
  imports: [BrowserModule, HttpClientModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }


於main.ts要去將引入的AppModule做路徑替換改為我們定義的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

//import { AppModule } from './app/app.module';
import { AppModule } from './mycomponents/student.module';
import { environment } from './environments/environment';

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

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));






當我們寫好後要運行
首先.net core WebApi專案需要先啟動
再來切至~\AngularApp 去下ng serve --open來開啟Angular Client端應用
當嘗試按下我們自行定義的元件中按鈕即可完成api get呼叫



這邊之所以能夠預設就選定用我們的元件來執行原因就在於
元件中選擇器的指定



這裡可以將於Startup.cs中開啟Cors機制註解
觀察angular呼叫結果就會出現違反同源政策的error訊息



這邊要再去擴充post請求
於student.component.ts 的 template中多增加按鈕與相應事件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { Component } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: '<button id="input1" (click)="getData()">獲得資料</button><br >' +
    '<button id="input2" (click)="addData()">添加資料</button>'
})

export class AppComponent {
  constructor(private http: HttpClient) { }
  url: string = 'http://localhost:15950/api/student/GetStudents';
  post_url: string = 'http://localhost:15950/api/student/addStudent';
  getData() {
    this.http.get(this.url).subscribe(function (result) {
      console.log(result);
    });
  }

  addData() {
    let body = JSON.stringify({ id: 4, name: 'Mike', age: 26, sex: 'male' });
    let headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    let options = { headers: headers };
    this.http.post(this.post_url, body, options).subscribe(function (result) {
      console.log(result);
    });
  }


}



可以看到angular成功呼叫post api














留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header