কৌণিক - প্রতিটি অনুরোধের জন্য শিরোনাম সেট করুন


334

পরবর্তী প্রতিটি অনুরোধের জন্য ব্যবহারকারী লগ ইন করার পরে আমাকে কিছু অনুমোদন শিরোনাম সেট করতে হবে।


একটি নির্দিষ্ট অনুরোধের জন্য শিরোনাম সেট করতে,

import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);

// HTTP POST using these headers
this.http.post(url, data, {
  headers: headers
})
// do something with the response

উল্লেখ

তবে প্রতিটি অনুরোধের জন্য এইভাবে অনুরোধ শিরোনামগুলি ম্যানুয়ালি সেট করা সম্ভব হবে না।

ব্যবহারকারী একবার লগ ইন করার পরে আমি শিরোলেখগুলি কীভাবে সেট করব এবং লগআউটে সেই শিরোনামগুলি সরিয়ে দেব?



উত্তর:


379

উত্তর দেওয়ার জন্য, আপনি প্রশ্ন করছেন যে আপনি এমন একটি পরিষেবা সরবরাহ করতে পারেন যা কৌনিক থেকে আসল Httpবস্তুটি মোড়বে। নীচে বর্ণিত মত কিছু।

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

@Injectable()
export class HttpClient {

  constructor(private http: Http) {}

  createAuthorizationHeader(headers: Headers) {
    headers.append('Authorization', 'Basic ' +
      btoa('username:password')); 
  }

  get(url) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.get(url, {
      headers: headers
    });
  }

  post(url, data) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.post(url, data, {
      headers: headers
    });
  }
}

এবং Httpঅবজেক্টটি ইনজেক্ট করার পরিবর্তে আপনি এইটি ( HttpClient) ইনজেক্ট করতে পারেন ।

import { HttpClient } from './http-client';

export class MyComponent {
  // Notice we inject "our" HttpClient here, naming it Http so it's easier
  constructor(http: HttpClient) {
    this.http = httpClient;
  }

  handleSomething() {
    this.http.post(url, data).subscribe(result => {
        // console.log( result );
    });
  }
}

আমি আরও মনে করি যে ক্লাসটির জন্য Httpআপনার নিজস্ব শ্রেণিটি প্রসারিত করে একাধিক সরবরাহকারীর ব্যবহার করে কিছু করা যেতে পারে Http... এই লিঙ্কটি দেখুন: http://blog.thoughtram.io/angular2/2015/11/23/m মাল্টি- প্রোভাইডার -ইন-কৌণিক -২.এইচটিএমএল


1
কোথায় 'this.http = http;' এসেছে, আমি বিশ্বাস করি ব্যবহারের আগে আমাদের এটি প্রকাশ করা দরকার?
co2f2e

1
কৌণিক শিরোনাম (সেট ও সংযোজন ফাংশন) শিরোনামের কীটি "স্বাভাবিককরণ" করছে এবং এটিকে লোয়ার-কেস করে তোলে। Headers.d.ts থেকে: // "HTTP- র অক্ষর সেট কেস-অবশ টোকেন দ্বারা শনাক্ত করা হয়" // ফটকা খেলা এ tools.ietf.org/html/rfc2616 যারা ব্যাকএন্ড নেই যে বৈশিষ্ট দ্বারা কাজ; এখানে একটি বাইপাস রয়েছে: আসুন হেডার্সম্যাপ = .get (বিকল্পগুলি, 'শিরোনামগুলি__হেডারম্যাপ', নতুন মানচিত্র ()); শিরোনামম্যাপ.সেট ('অনুমোদন', [ .replace ( Bearer ${token}, / / ​​\ "/ জি, '")]));
সংগীত

@ ডিগোউনানু আমি কৌনিক 2 এবং থিয়েরির বাস্তবায়ন কাজগুলির চূড়ান্ত সংস্করণটি ব্যবহার করছি। আমদানি বিবৃতিগুলিতে কেবল 'কৌণিক 2' কে '@angular' এ প্রতিস্থাপন করুন।
f123

পাইকসাককে চিহ্নিত করুন- আমি কি এইচটিপিপি্লায়েন্টের জন্য সরবরাহকারীদের অন্তর্ভুক্ত করব?
ব্যবহারকারী3127109

এখন টিএস ত্রুটি ছুঁড়েছে: 'প্রকারের যুক্তি' {শিরোনাম: শিরোনাম; 'রিকোয়েস্টঅপশনস অর্গস'`
এলপোরফিরিও

142

HTTP- র interceptors খুব হয় এখন উপলব্ধ নতুন মাধ্যমে HttpClientথেকে @angular/common/http, কৌণিক 4.3.x সংস্করণ এবং তার পরেও হিসাবে

এখন প্রতিটি অনুরোধের জন্য শিরোনাম যুক্ত করা বেশ সহজ:

import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';

export class AddHeaderInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Clone the request to add the new header
    const clonedRequest = req.clone({ headers: req.headers.set('Authorization', 'Bearer 123') });

    // Pass the cloned request instead of the original request to the next handle
    return next.handle(clonedRequest);
  }
}

অপরিবর্তনীয়তার একটি মূলনীতি রয়েছে , এ কারণেই এটিতে নতুন কিছু সেট করার আগে অনুরোধটির ক্লোন করা প্রয়োজন।

শিরোনাম সম্পাদনা করা খুব সাধারণ কাজ হওয়ায় এটির জন্য আসলে একটি শর্টকাট রয়েছে (অনুরোধটি ক্লোন করার সময়):

const clonedRequest = req.clone({ setHeaders: { Authorization: 'Bearer 123' } });

ইন্টারসেপটর তৈরির পরে, আপনার সরবরাহটি ব্যবহার করে এটি নিবন্ধভুক্ত করা উচিত HTTP_INTERCEPTORS

import { HTTP_INTERCEPTORS } from '@angular/common/http';

@NgModule({
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: AddHeaderInterceptor,
    multi: true,
  }],
})
export class AppModule {}

আমি এটি বাস্তবায়ন করেছি এবং এনজি সার্ভিস করার সময় আমি অনুরোধ শিরোনাম দেখতে পাচ্ছি, তবে এনজি বি প্রোড করার সময় এবং টমক্যাটের ভিতরে স্থাপন করার সময়, আমি শিরোনামগুলি দেখতে পাই না ... বসন্ত-বুট ব্যবহার করে, শিরোনামগুলি কোথায় গেল?
নওরো

1
জানি না এটি কারণ আমি একটি এক্সপ্রেস নোড এপিআই নিয়ে কাজ করছি তবে এটি অফিসিয়াল কৌণিক ডক দিয়েও আমার পক্ষে কাজ করে না। : /
ম্যাক্সিম লাফারি

ত্রুটি প্রকারের ত্রুটি: ক্রিয়েটলিস্টফ্রমেআরাই লাইক অ-অবজেক্টকে ডেকেছে
ডাগ

1
আপনি কীভাবে এইচটিটিপিআইন্টারসেপ্টারে ইনজেক্ট করবেন?
জাইটসমান

আমি এই একই জিনিসগুলি বাস্তবায়ন করেছি কিন্তু পুট এবং ডিলি এপিআই অনুরোধ শিরোনামটি আমার পক্ষে কাজ করে না।
পূজা

78

এই দৃশ্যে প্রসারিত করা বড় সহায়ক BaseRequestOptionsহতে পারে। নিম্নলিখিত কোডটি দেখুন:

import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';

import {AppCmp} from './components/app/app';


class MyRequestOptions extends BaseRequestOptions {
  constructor () {
    super();
    this.headers.append('My-Custom-Header','MyCustomHeaderValue');
  }
} 

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(RequestOptions, { useClass: MyRequestOptions })
]);

এর মধ্যে প্রতিটি কলে 'মাই-কাস্টম-শিরোনাম' অন্তর্ভুক্ত করা উচিত।

হালনাগাদ:

উপরের কোডের পরিবর্তে আপনি যে কোনও সময় চাইলে শিরোনামটি পরিবর্তন করতে সক্ষম হতে একটি নতুন শিরোনাম যুক্ত করতে নিম্নলিখিত কোডগুলিও ব্যবহার করতে পারেন:

this.http._defaultOptions.headers.append('Authorization', 'token');

মুছতে আপনি করতে পারেন

this.http._defaultOptions.headers.delete('Authorization');

এছাড়াও আরেকটি ফাংশন রয়েছে যা আপনি মান সেট করতে ব্যবহার করতে পারেন:

this.http._defaultOptions.headers.set('Authorization', 'token');

উপরে সমাধান এখনও টাইপস্ক্রিপ্ট প্রসঙ্গে সম্পূর্ণ বৈধ নয়। _ডিফাল্টহাইডার্স সুরক্ষিত এবং এই জাতীয় ব্যবহারের কথা নয়। আমি দ্রুত সমাধানের জন্য উপরের সমাধানটি সুপারিশ করব তবে দীর্ঘ সময়ের জন্য এইচটিপি কলগুলির আশেপাশে আপনার নিজের র‍্যাপারটি লেখার পক্ষে এটি আরও ভাল। Auth0 থেকে নিম্নলিখিত উদাহরণটি নিন যা আরও ভাল এবং পরিষ্কার।

https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts

আপডেট - জুন 2018 আমি দেখতে পাচ্ছি প্রচুর লোক এই সমাধানের জন্য যাচ্ছেন তবে আমি অন্যথায় পরামর্শ দেব। বিশ্বব্যাপী শিরোনাম যুক্ত করা আপনার অ্যাপ্লিকেশন থেকে বেরিয়ে আসা প্রতিটি এপিআই কলটিতে অথথ টোকন প্রেরণ করবে । তাই আন্তঃকম বা জেন্ডেস্ক বা অন্য কোনও এপিআই যেমন তৃতীয় পক্ষের প্লাগইনগুলিতে যাওয়া এপিআই কলগুলিও আপনার অনুমোদনের শিরোনাম বহন করবে। এর ফলে একটি বৃহত সুরক্ষা ত্রুটি হতে পারে। সুতরাং পরিবর্তে, বিশ্বব্যাপী ইন্টারসেপ্টর ব্যবহার করুন তবে বহির্গামী কলটি আপনার সার্ভারের এপিআই শেষ পয়েন্টের দিকে আছে কিনা তা নিজেই যাচাই করুন এবং তারপরে প্রমাণী শিরোনাম সংযুক্ত করুন।


1
this.http._defaultOptions.headers.delete ('আমার-কাস্টম-শিরোলেখ') সুতরাং উপরের প্রক্রিয়াটি নীচের কোডের মাধ্যমে সংক্ষিপ্ত করা যেতে পারে এই এইচটিটিএইচটিপি_ডিফল্টঅ্যাপশন.হেডারস.এপেন্ড ('আমার-নতুন-কাস্টম-শিরোলেখ', 'নতুন মূল্য ')
আনিত

2
@ ডিনিস্ট্রো হ্যাঁ, এখন আমি নিজেকে এটি করার পরামর্শ দেব না। কৌণিক বিটা সীমাবদ্ধতা এবং বিশ্বব্যাপী আমার লেখার প্রবাহকে নিয়ন্ত্রণ করার অভ্যাসের কারণে আমাকে এই কর্মসূচীটি নিয়ে আসতে হয়েছিল। তবে আমি বিশ্বাস করি আপাতত github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts এর আরও ভাল এবং পরিষ্কার সমাধান রয়েছে।
অনিত

1
বেসরেকোস্টঅ্যাপশনগুলি ব্যবহার করার সমস্যাটি হ'ল এটির নির্মাতা ব্রাউজারে অ্যাপ্লিকেশন জীবদ্দশায় কেবল একবার চালিত হয়। সুতরাং আপনি যদি সময়কালে শিরোনামের মান পরিবর্তন করতে চান (যেমন csrf_token) আপনি এই উপায়ে এটি করতে পারবেন না (এমনকি এই শ্রেণীর মধ্যে একত্রীকরণের পদ্ধতিটিও সহায়তা করে না :()
কামিল কিয়েসজেউস্কি

1
সমস্যাটি হ'ল আপনি যদি এমন একটি মোড়ক ব্যবহার করেন তৃতীয় পক্ষের লাইব্রেরি যা HTTP ব্যবহার করতে সরাসরি এটি ব্যবহার করতে পুনরায় লেখা দরকার। আমি এখনও কিভাবে জানি না। একটি ইন্টারসেপ্টর সত্যই প্রয়োজন। কেউ আরও ভাল উপায় জানেন কিনা তা নিশ্চিত নয়।
পাইটর স্টুলিনস্কি

6
হাই, কৌণিক 4 _defaultOptionsএ সুরক্ষিত রয়েছে তাই পরিষেবা থেকে কল করা যাবে না
Andurit

24

যদিও আমি খুব দেরিতে এর উত্তর দিচ্ছি তবে এটি অন্য কারও পক্ষে সহায়তা করতে পারে। @NgModuleব্যবহৃত হওয়ার সময় সমস্ত অনুরোধে শিরোনাম ইনজেক্ট করতে, নিম্নলিখিত ব্যক্তিরা নিম্নলিখিতটি করতে পারেন:

(আমি এঙ্গুলার ২.০.২ এ পরীক্ষা করেছি)

/**
 * Extending BaseRequestOptions to inject common headers to all requests.
 */
class CustomRequestOptions extends BaseRequestOptions {
    constructor() {
        super();
        this.headers.append('Authorization', 'my-token');
        this.headers.append('foo', 'bar');
    }
}

এখন @NgModuleনিম্নলিখিত কাজগুলি করুন:

@NgModule({
    declarations: [FooComponent],
    imports     : [

        // Angular modules
        BrowserModule,
        HttpModule,         // This is required

        /* other modules */
    ],
    providers   : [
        {provide: LocationStrategy, useClass: HashLocationStrategy},
        // This is the main part. We are telling Angular to provide an instance of
        // CustomRequestOptions whenever someone injects RequestOptions
        {provide: RequestOptions, useClass: CustomRequestOptions}
    ],
    bootstrap   : [AppComponent]
})

4
আপনার ক্লাসে ইনজেক্টেবল এবং শিরোনামগুলি সংজ্ঞায়িত করা দরকার, আমি @ ইনজেক্টেবল () এক্সপোর্ট ক্লাস কাস্টমরেকুস্টঅপশনগুলি বেসরেকুয়েস্টপশনস s শিরোনামগুলি প্রসারিত করে সফল পরীক্ষা করেছি: শিরোনাম = নতুন শিরোনাম ({'অনুমোদন': 'xxx'}); ।
सनব্ল্যাক

ভাল, আমি
২.০.০

গুরুত্বপূর্ণ নোট এখানে আমি একটি ইস্যুতে দৌড়েছি যেখানে CustomRequestOptions@ ইনজেক্ট / @ ইনজেকশনযোগ্য ব্যবহার করার পরেও কোনও কিছুতে ইনজেক্ট করা অসম্ভব ছিল । সমাধান আমি উপলব্ধি প্রসারিত ছিল RequestOptionsনা BaseRequestOptions। সরবরাহ করা BaseRequestOptionsকাজ করবে না, তবে RequestOptionsপরিবর্তে প্রসারিত করা ডিআইকে আবার কাজ করে।
সংসদ

5
এই সমাধানটি সহজ, তবে যদি ব্যবহারকারী লগ আউট করে আবার লগ ইন করে এবং তার টোকেন পরিবর্তন করে - এটি আর কাজ করবে না, কারণ Authorizationশিরোনামটি অ্যাপ্লিকেশন ইন-তে একবার মাত্র সেট করা আছে।
অ্যালেক্স প্যারমনভ

হ্যাঁ, সঠিক @ অ্যালেক্সিভিপারামনোভ। টোকন একবার সেট করা থাকলে এটি কেবল কার্যকর। অন্যথায় আমরা যেমনটি বলেছিলাম তেমন মামলার জন্য আমরা ইন্টারসেপ্টর লিখব।
শশাঙ্ক অগ্রওয়াল

15

ইন Angular 2.1.2আমি ব্যাপ্ত দ্বারা এই কাছে কৌণিক http:

import {Injectable} from "@angular/core";
import {Http, Headers, RequestOptionsArgs, Request, Response, ConnectionBackend, RequestOptions} from "@angular/http";
import {Observable} from 'rxjs/Observable';

@Injectable()
export class HttpClient extends Http {

  constructor(protected _backend: ConnectionBackend, protected _defaultOptions: RequestOptions) {

    super(_backend, _defaultOptions);
  }

  _setCustomHeaders(options?: RequestOptionsArgs):RequestOptionsArgs{
    if(!options) {
      options = new RequestOptions({});
    }
    if(localStorage.getItem("id_token")) {

      if (!options.headers) {

        options.headers = new Headers();


      }
      options.headers.set("Authorization", localStorage.getItem("id_token"))
    }
    return options;
  }


  request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);
    return super.request(url, options)
  }
}

তারপরে আমার অ্যাপ সরবরাহকারীগুলিতে আমি 'এইচটিপি' সরবরাহ করতে একটি কাস্টম কারখানা ব্যবহার করতে সক্ষম হয়েছি

import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';
import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';//above snippet

function httpClientFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
  return new HttpClient(xhrBackend, requestOptions);
}

@NgModule({
  imports:[
    FormsModule,
    BrowserModule,
  ],
  declarations: APP_DECLARATIONS,
  bootstrap:[AppComponent],
  providers:[
     { provide: Http, useFactory: httpClientFactory, deps: [XHRBackend, RequestOptions]}
  ],
})
export class AppModule {
  constructor(){

  }
}

এখন আমাকে প্রতিটি এইচটিপিপি পদ্ধতি ঘোষণা করার দরকার নেই এবং httpআমার অ্যাপ্লিকেশন জুড়ে স্বাভাবিক হিসাবে ব্যবহার করতে পারি।


এই উত্তরটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে যেহেতু আমি আমার এপিআই সার্ভারে ইউআরএল ফিল্টার করতে সক্ষম হয়েছি এবং কেবলমাত্র এটিতে করা কলগুলিতে আউথ টোকেন যুক্ত করতে পারি। আমি অনুরোধটি এতে পরিবর্তন করেছি: অনুরোধ (ইউআরএল: স্ট্রিং | অনুরোধ, বিকল্পগুলি? অনুরোধওপশনস অর্গস): পর্যবেক্ষণযোগ্য <রিসপনস> _ var _url: স্ট্রিং = url.toString (); if (_url.indexOf ('api.myserver.com')> -1) {বিকল্পগুলি = this._setCustomHeedia (বিকল্প); super সুপার.রেউকস্ট (url, বিকল্পগুলি) ফিরে আসুন}
ক্রিস হলকম্ব

আমার ক্ষেত্রে ক্রেনডেনটিয়ালস এবং শিরোনামগুলি অনুরোধ পদ্ধতিতে ইউআরএল প্যারামিটার থেকে নেওয়া হয়েছিল। আমি এই জাতীয় কোড পরিবর্তন করেছি: অনুরোধ (url: স্ট্রিং | অনুরোধ, বিকল্পগুলি ?: অনুরোধঅપ્শনস অর্গস): পর্যবেক্ষণযোগ্য <রিসপনস> {বিকল্পগুলি = এটি ._সেটকাস্টমহাইডার্স (বিকল্প); if (টাইপফ (url) === "অবজেক্ট") {(<অনুরোধ> ইউআরএল) (<অনুসন্ধান> ইউআরএল)। শিরোনাম = অপশন.হেডারস; super সুপার.রেউকস্ট (url, বিকল্পগুলি)
ফিরিয়ে দিন

request()পদ্ধতি, যা আপনি ওভারলোডিং হয়, দুই কল স্বাক্ষর এবং optionsসম্পত্তি শুধুমাত্র যখন ব্যবহার করা হয় urlস্ট্রিং হিসেবে নির্দিষ্ট করা হয়েছে। কেস যেখানে সালে urlএকটি দৃষ্টান্ত হল Request, optionsসম্পত্তি মাত্র উপেক্ষা করা হয়। এর ফলে ত্রুটিগুলি ধরা শক্ত হতে পারে। আরও তথ্যের জন্য দয়া করে আমার উত্তর দেখুন।
স্লাভা ফমিন II


এটি আমার পক্ষে কৌনিক 4.2 অবধি কাজ করেছিল। ৪.৩ এর ইন্টারসেপ্টর রয়েছে।
ক্যাবিজি 99

12

কৌণিক 2 Httpসরবরাহকারীর প্রসারিত করে একটি কাস্টম এইচটিপি ক্লাস তৈরি করুন এবং কেবলমাত্র আপনার কাস্টম এইচটিপি ক্লাসে constructorrequestপদ্ধতিটি ওভাররাইড করুন । নীচের উদাহরণটি Authorizationপ্রতিটি http অনুরোধে শিরোনাম যুক্ত করে।

import {Injectable} from '@angular/core';
import {Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class HttpService extends Http {

  constructor (backend: XHRBackend, options: RequestOptions) {
    let token = localStorage.getItem('auth_token'); // your custom token getter function here
    options.headers.set('Authorization', `Bearer ${token}`);
    super(backend, options);
  }

  request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    let token = localStorage.getItem('auth_token');
    if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
      if (!options) {
        // let's make option object
        options = {headers: new Headers()};
      }
      options.headers.set('Authorization', `Bearer ${token}`);
    } else {
    // we have to add the token to the url object
      url.headers.set('Authorization', `Bearer ${token}`);
    }
    return super.request(url, options).catch(this.catchAuthError(this));
  }

  private catchAuthError (self: HttpService) {
    // we have to pass HttpService's own instance here as `self`
    return (res: Response) => {
      console.log(res);
      if (res.status === 401 || res.status === 403) {
        // if not authenticated
        console.log(res);
      }
      return Observable.throw(res);
    };
  }
}

তারপর আপনার প্রধান কনফিগার app.module.tsপ্রদান XHRBackendহিসাবে ConnectionBackendপ্রদানকারী এবং RequestOptionsআপনার কাস্টম HTTP ক্লাসে:

import { HttpModule, RequestOptions, XHRBackend } from '@angular/http';
import { HttpService } from './services/http.service';
...
@NgModule({
  imports: [..],
  providers: [
    {
      provide: HttpService,
      useFactory: (backend: XHRBackend, options: RequestOptions) => {
        return new HttpService(backend, options);
      },
      deps: [XHRBackend, RequestOptions]
    }
  ],
  bootstrap: [ AppComponent ]
})

এর পরে, আপনি এখন আপনার পরিষেবাগুলিতে আপনার কাস্টম HTTP সরবরাহকারীর ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:

import { Injectable }     from '@angular/core';
import {HttpService} from './http.service';

@Injectable()
class UserService {
  constructor (private http: HttpService) {}

  // token will added automatically to get request header
  getUser (id: number) {
    return this.http.get(`/users/${id}`).map((res) => {
      return res.json();
    } );
  }
}

এখানে একটি বিস্তৃত গাইড - http://adonespitogo.com/articles/angular-2-extending-http-provider/


এই পদ্ধতির বিকল্প শ্রেণীর সরবরাহকারী ব্যবহারের জন্য উপযুক্ত। আপনার মডিউলে যেমন "সরবরাহ করুন: এইচটিটিপিএস সার্ভিস" পরিবর্তে আপনি "সরবরাহ করুন: এইচটিটিপি" ব্যবহার করতে পারেন তবে আপনি সাধারণত যেভাবে এইচটিটিপি দিয়ে কাজ করতে পারবেন।
গিলবার্ট অ্যারেনাস ড্যাজার

এই বর্ধিত এইচটিপি ক্লাসে আমি কীভাবে অতিরিক্ত সম্পত্তি যুক্ত করতে পারি? উদাহরণস্বরূপ, রাউটার: রাউটার বা কোনও কাস্টম ইনজেকশনযোগ্য পরিষেবা।
shafiquemat

@ shafiquemat আপনি এটি ব্যবহার করে এটি করতে পারবেন না। উদাহরণস্বরূপ, আপনি আপনার কাস্টম http শ্রেণিতে অন্য কোনও পদ্ধতি নির্ধারণ করতে পারেন setRouter(router)। অথবা আপনি অন্য শ্রেণি তৈরি করতে পারেন এবং বিপরীতে পরিবর্তে সেখানে নিজের কাস্টম এইচটিপি ক্লাসটি ইনজেক্ট করতে পারেন।
অ্যাডোনস পিটোগো 20'18

9

5 এবং ততোধিক কৌণিকের জন্য, আমরা অনুরোধ এবং প্রতিক্রিয়া ক্রিয়াকলাপের জন্য HTTPIntercepter ব্যবহার করতে পারি। এটি আমাদের সদৃশ এড়াতে সহায়তা করে:

1) সাধারণ শিরোনাম

2) প্রতিক্রিয়া প্রকার উল্লেখ

3) অনুরোধ অনুরোধ

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {

  requestCounter: number = 0;
  constructor() {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    request = request.clone({
      responseType: 'json',
      setHeaders: {
        Authorization: `Bearer token_value`,
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    });

    return next.handle(request).do((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        // do stuff with response if you want
      }
    }, (err: any) => {
      if (err instanceof HttpErrorResponse) {
        // do stuff with response error if you want
      }
    });
  }
}

এই এইচটিএইচটিপিআইএনটারসেপ্টর ক্লাসটি এইচটিটিপিআইন্টারসেপ্টরগুলির সরবরাহকারী হিসাবে ব্যবহার করতে পারি:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing-module';
import { AuthHttpInterceptor } from './services/auth-http.interceptor';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthHttpInterceptor,
      multi: true
    }
  ],
  exports: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}

8

কখনও না থেকে আরও দেরী ... =)

আপনি বর্ধিত ধারণাটি নিতে পারেন BaseRequestOptions(এখান থেকে https://angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options ) এবং উড়ে "হেডারে রিফ্রেশ করুন" "(কেবলমাত্র নির্মাণকারী নয়)। আপনি গেটর / সেটার "হেডার" বৈশিষ্ট্যটিকে এভাবে ওভাররাইড ব্যবহার করতে পারেন:

import { Injectable } from '@angular/core';
import { BaseRequestOptions, RequestOptions, Headers } from '@angular/http';

@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions {

    private superHeaders: Headers;

    get headers() {
        // Set the default 'Content-Type' header
        this.superHeaders.set('Content-Type', 'application/json');

        const token = localStorage.getItem('authToken');
        if(token) {
            this.superHeaders.set('Authorization', `Bearer ${token}`);
        } else {
            this.superHeaders.delete('Authorization');
        }
        return this.superHeaders;
    }

    set headers(headers: Headers) {
        this.superHeaders = headers;
    }

    constructor() {
        super();
    }
}

export const requestOptionsProvider = { provide: RequestOptions, useClass: DefaultRequestOptions };

সামান্য আপডেট: ভাল পারফরম্যান্সের জন্য আপনি সমস্ত স্ট্যাটিক শিরোলেখ (যেমন 'বিষয়বস্তুর ধরণ') কনস্ট্রাক্টরে সরানো বিবেচনা করতে পারেন
25

7

প্রতিটি অনুরোধের সাথে টোকেন সেট করার জন্য আমি এইভাবে করেছি।

import { RequestOptions, BaseRequestOptions, RequestOptionsArgs } from '@angular/http';

export class CustomRequestOptions extends BaseRequestOptions {

    constructor() {
        super();
        this.headers.set('Content-Type', 'application/json');
    }
    merge(options?: RequestOptionsArgs): RequestOptions {
        const token = localStorage.getItem('token');
        const newOptions = super.merge(options);
        if (token) {
            newOptions.headers.set('Authorization', `Bearer ${token}`);
        }

        return newOptions;
    }
}

এবং app.module.ts এ নিবন্ধন করুন

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule
    ],
    providers: [
        { provide: RequestOptions, useClass: CustomRequestOptions }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

6

Angular2 ফাইনালের জন্য আপডেট হওয়া স্বীকৃত উত্তরের একটি উন্নত সংস্করণ এখানে রয়েছে:

import {Injectable} from "@angular/core";
import {Http, Headers, Response, Request, BaseRequestOptions, RequestMethod} from "@angular/http";
import {I18nService} from "../lang-picker/i18n.service";
import {Observable} from "rxjs";
@Injectable()
export class HttpClient {

    constructor(private http: Http, private i18n: I18nService ) {}

    get(url:string):Observable<Response> {
        return this.request(url, RequestMethod.Get);
    }

    post(url:string, body:any) {   
        return this.request(url, RequestMethod.Post, body);
    }

    private request(url:string, method:RequestMethod, body?:any):Observable<Response>{

        let headers = new Headers();
        this.createAcceptLanguageHeader(headers);

        let options = new BaseRequestOptions();
        options.headers = headers;
        options.url = url;
        options.method = method;
        options.body = body;
        options.withCredentials = true;

        let request = new Request(options);

        return this.http.request(request);
    }

    // set the accept-language header using the value from i18n service that holds the language currently selected by the user
    private createAcceptLanguageHeader(headers:Headers) {

        headers.append('Accept-Language', this.i18n.getCurrentLang());
    }
}

অবশ্যই এটির মতো পদ্ধতির জন্য প্রসারিত হওয়া উচিত deleteএবং putযদি প্রয়োজন হয় (আমার প্রকল্পের এই মুহুর্তে আমার এখনও তাদের প্রয়োজন হয় না)।

সুবিধাটি হ'ল get/ post/ ... পদ্ধতিগুলিতে কম সদৃশ কোড রয়েছে ।

মনে রাখবেন যে আমার ক্ষেত্রে আমি প্রমাণীকরণের জন্য কুকি ব্যবহার করি। আই 18 এন ( Accept-Languageহেডার) এর জন্য আমার শিরোনামের প্রয়োজন ছিল কারণ আমাদের এপিআই দ্বারা ফিরিয়ে নেওয়া অনেকগুলি মান ব্যবহারকারীর ভাষায় অনুবাদ করা হয়। আমার অ্যাপ্লিকেশনটিতে আই 18 এন পরিষেবা বর্তমানে ব্যবহারকারী দ্বারা নির্বাচিত ভাষা ধারণ করে।


লেট হিসাবে শিরোনাম উপেক্ষা করার জন্য আপনি কীভাবে স্লিন্ট পেয়েছিলেন?
Winnemucca

5

নীচের মতো পৃথক পরিষেবা রাখার বিষয়ে কীভাবে

            import {Injectable} from '@angular/core';
            import {Headers, Http, RequestOptions} from '@angular/http';


            @Injectable()
            export class HttpClientService extends RequestOptions {

                constructor(private requestOptionArgs:RequestOptions) {
                    super();     
                }

                addHeader(headerName: string, headerValue: string ){
                    (this.requestOptionArgs.headers as Headers).set(headerName, headerValue);
                }
            }

এবং আপনি অন্য জায়গা থেকে কল করার সময় এটি ব্যবহার করুন this.httpClientService.addHeader("Authorization", "Bearer " + this.tok);

এবং জুড়েছে হেডার যেমন দেখতে হবে: - অনুমোদন নিম্নরূপ

এখানে চিত্র বর্ণনা লিখুন


5

কিছু তদন্তের পরে, আমি চূড়ান্ত খুঁজে পেয়েছি এবং সবচেয়ে সহজ উপায়টি BaseRequestOptionsআমি পছন্দ করি যা প্রসারিত করা ।
নীচে আমি যেভাবে চেষ্টা করেছি এবং কোনও কারণে ছেড়ে দিয়েছি:
1. প্রসারিত BaseRequestOptionsকরুন এবং এতে গতিশীল শিরোনাম যুক্ত করুন constructor()। আমি লগইন করলে এটি কাজ করতে পারে না। এটি একবার তৈরি করা হবে। সুতরাং এটি গতিশীল নয়।
2. প্রসারিত Http। উপরের মত একই কারণে, আমি গতিশীল শিরোলেখগুলিতে যুক্ত করতে পারি না constructor()। এবং যদি আমি request(..)পদ্ধতিটি আবার লিখি এবং শিরোনামগুলি সেট করে রাখি :

request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
 let token = localStorage.getItem(AppConstants.tokenName);
 if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
  if (!options) {
    options = new RequestOptions({});
  }
  options.headers.set('Authorization', 'token_value');
 } else {
  url.headers.set('Authorization', 'token_value');
 }
 return super.request(url, options).catch(this.catchAuthError(this));
}

আপনার কেবল এই পদ্ধতিটি ওভাররাইট করতে হবে তবে প্রতিটি গেইট / পোস্ট / পুট পদ্ধতি নয়।

৩.আর আমার পছন্দের সমাধানটি প্রসারিত BaseRequestOptionsএবং ওভাররাইট করা হবে merge():

@Injectable()
export class AuthRequestOptions extends BaseRequestOptions {

 merge(options?: RequestOptionsArgs): RequestOptions {
  var newOptions = super.merge(options);
  let token = localStorage.getItem(AppConstants.tokenName);
  newOptions.headers.set(AppConstants.authHeaderName, token);
  return newOptions;
 }
}

এই merge()অনুরোধটি প্রতিটি অনুরোধের জন্য ডাকা হবে।


প্রদত্ত সমস্ত উত্তরগুলির মধ্যে, এই উত্তরটি আমার দৃষ্টি আকর্ষণ করেছে যেহেতু আমি ইতিমধ্যে একটি সমাধানের জন্য গিয়েছি যা বাড়ানোর উপর ভিত্তি করে BaseRequestOptions। তবে দুঃখের বিষয়, এটি আমার পক্ষে কার্যকর হয়নি। কোন সম্ভাব্য কারণ?
উইগামেজ

এটা কাজ পেয়েছিলাম। এই সমাধানটি ঠিক আছে এবং আমার সার্ভারে আমার একটি সমস্যা হয়েছিল। আমাকে সিওআরএস প্রাক-উড়ানের অনুরোধগুলির জন্য কিছু কনফিগারেশন করতে হয়েছিল। এই লিঙ্কে পড়ুন stackoverflow.com/a/43962690/3892439
vigamage

কীভাবে আপনি AuthRequestOptionsবাকী অ্যাপে টাই করবেন ? আমি এটি providersবিভাগে রাখার চেষ্টা করেছি তবে এটি কিছুই করেনি।
ট্র্যাভিস পার্কগুলি

আপনাকে অবশ্যই সরবরাহকারীকে ওভাররাইড করতে হবে RequestOptions, না BaseRequestOptionsAngular.io/api/http/BaseRequestOptions
ট্র্যাভিস পার্ক

আমার অ্যাপ্লিকেশনটিতে, আমি কেবল বেসরেকোস্টঅ্যাপশনগুলি প্রসারিত করেছি এবং এটি ইতিমধ্যে অনুরোধ অপশনগুলি প্রসারিত করে। তারপরে অ্যাপ্লিকেশন.মডিউলটিতে আপনার সরবরাহকারীদের সেট করা উচিত:{ provide: RequestOptions, useClass: AuthRequestOptions }
মাভালার্ন

5

যদিও আমি খুব দেরিতে উত্তর দিচ্ছি তবে যদি কেউ এর চেয়ে সহজ সমাধান খুঁজছেন।

আমরা কৌণিক 2-jwt ব্যবহার করতে পারি। একটি কৌণিক 2 অ্যাপ্লিকেশন থেকে এইচটিটিপি অনুরোধ করার সময় কৌণিক 2-jwt স্বয়ংক্রিয়ভাবে একটি JSON ওয়েব টোকেন (জেডাব্লুটি) কে অনুমোদনের শিরোনাম হিসাবে সংযুক্ত করা কার্যকর।

আমরা উন্নত কনফিগারেশন বিকল্প সহ গ্লোবাল শিরোনাম সেট করতে পারি

export function authHttpServiceFactory(http: Http, options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName: 'token',
        tokenGetter: (() => sessionStorage.getItem('token')),
        globalHeaders: [{'Content-Type':'application/json'}],
    }), http, options);
}

এবং প্রতি অনুরোধ টোকেন প্রেরণ

    getThing() {
  let myHeader = new Headers();
  myHeader.append('Content-Type', 'application/json');

  this.authHttp.get('http://example.com/api/thing', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );

  // Pass it after the body in a POST request
  this.authHttp.post('http://example.com/api/thing', 'post body', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );
}

Github.com/auth0/angular2-jwt# ইনস্টল করার জন্য এবং তাদের ইনস্টলেশন গাইড ব্যবহার করে এই উত্তরটি অভিযোজিত করতে সহায়ক হবে
জুনিয়াল

4

আমি ডিফল্ট বিকল্পগুলিকে ওভাররাইড করার ধারণাটি পছন্দ করি, এটি একটি ভাল সমাধান বলে মনে হচ্ছে।

তবে, আপনি যদি প্রসারিত করতে চান Http ক্লাস । এটি মাধ্যমে নিশ্চিত করুন!

কিছু উত্তর এখানে প্রকৃতপক্ষে ভুল ওভারলোডিং দেখাচ্ছে request() পদ্ধতির , যা ধরা পড়ার জন্য ত্রুটি এবং অদ্ভুত আচরণের কারণ হতে পারে। আমি নিজেই হোঁচট খেয়েছি।

এই সমাধানটি request()কৌণিক পদ্ধতিতে প্রয়োগের উপর ভিত্তি করে 4.2.x, তবে ভবিষ্যতে সামঞ্জস্যপূর্ণ হওয়া উচিত:

import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';

import {
  ConnectionBackend, Headers,
  Http as NgHttp,
  Request,
  RequestOptions,
  RequestOptionsArgs,
  Response,
  XHRBackend
} from '@angular/http';


import {AuthenticationStateService} from '../authentication/authentication-state.service';


@Injectable()
export class Http extends NgHttp {

  constructor (
    backend: ConnectionBackend,
    defaultOptions: RequestOptions,
    private authenticationStateService: AuthenticationStateService
  ) {
    super(backend, defaultOptions);
  }


  request (url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

    if ('string' === typeof url) {

      url = this.rewriteUrl(url);
      options = (options || new RequestOptions());
      options.headers = this.updateHeaders(options.headers);

      return super.request(url, options);

    } else if (url instanceof Request) {

      const request = url;
      request.url = this.rewriteUrl(request.url);
      request.headers = this.updateHeaders(request.headers);

      return super.request(request);

    } else {
      throw new Error('First argument must be a url string or Request instance');
    }

  }


  private rewriteUrl (url: string) {
    return environment.backendBaseUrl + url;
  }

  private updateHeaders (headers?: Headers) {

    headers = headers || new Headers();

    // Authenticating the request.
    if (this.authenticationStateService.isAuthenticated() && !headers.has('Authorization')) {
      headers.append('Authorization', 'Bearer ' + this.authenticationStateService.getToken());
    }

    return headers;

  }

}

লক্ষ্য করুন যে import { Http as NgHttp } from '@angular/http';নাম সংঘর্ষ রোধ করতে আমি এইভাবে মূল ক্লাসটি আমদানি করছি ।

এখানে সমস্যাটি হ'ল সমস্যাটি হ'ল request()পদ্ধতিটিতে দুটি পৃথক কল স্বাক্ষর রয়েছে। যখন Requestবস্তুর URL এর পরিবর্তে পাস করা হয়েছে string, optionsযুক্তি কৌণিক দ্বারা উপেক্ষা করা হয়। সুতরাং উভয় কেস সঠিকভাবে পরিচালনা করতে হবে।

এবং ডিআই কনটেইনার দিয়ে এই ওভাররাইড ক্লাসটি কীভাবে নিবন্ধিত করবেন তার উদাহরণ এখানে:

export const httpProvider = {
  provide: NgHttp,
  useFactory: httpFactory,
  deps: [XHRBackend, RequestOptions, AuthenticationStateService]
};


export function httpFactory (
  xhrBackend: XHRBackend,
  requestOptions: RequestOptions,
  authenticationStateService: AuthenticationStateService
): Http {
  return new Http(
    xhrBackend,
    requestOptions,
    authenticationStateService
  );
}

এই জাতীয় পদ্ধতির সাহায্যে আপনি ইনজেকশন করতে পারেন Http সাধারণত ক্লাসটি তবে আপনার ওভাররাইড হওয়া ক্লাসটি পরিবর্তে যাদুতে ইনজেকশন দেওয়া হবে। এটি আপনাকে অ্যাপ্লিকেশনের অন্যান্য অংশগুলি (ক্রিয়ায় পলিমারফিজম) পরিবর্তন না করে সহজেই আপনার সমাধানকে সংহত করতে দেয় allows

শুধু যোগ httpProviderকরতে providersআপনার মডিউল মেটাডেটার সম্পত্তি।


1

সব থেকে সহজ

একটি config.tsফাইল তৈরি করুন

import { HttpHeaders } from '@angular/common/http';

export class Config {
    url: string = 'http://localhost:3000';
    httpOptions: any = {
        headers: new HttpHeaders({
           'Content-Type': 'application/json',
           'Authorization': JSON.parse(localStorage.getItem('currentUser')).token
        })
    }
}

তারপরে service, কেবল config.tsফাইলটি আমদানি করুন

import { Config } from '../config';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class OrganizationService {
  config = new Config;

  constructor(
    private http: HttpClient
  ) { }

  addData(data): Observable<any> {
     let sendAddLink = `${this.config.url}/api/addData`;

     return this.http.post(sendAddLink , data, this.config.httpOptions).pipe(
       tap(snap => {
      return snap;
        })
    );
 } 

আমি মনে করি এটি সবচেয়ে সহজ এবং নিরাপদ ছিল।


0

কৌণিক ২.০.১ এবং এর চেয়েও বেশি কিছু পরিবর্তন রয়েছে:

    import {RequestOptions, RequestMethod, Headers} from '@angular/http';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpModule }     from '@angular/http';
    import { AppRoutingModule } from './app.routing.module';   
    import { AppComponent }  from './app.component';

    //you can move this class to a better place
    class GlobalHttpOptions extends RequestOptions {
        constructor() { 
          super({ 
            method: RequestMethod.Get,
            headers: new Headers({
              'MyHeader': 'MyHeaderValue',
            })
          });
        }
      }

    @NgModule({

      imports:      [ BrowserModule, HttpModule, AppRoutingModule ],
      declarations: [ AppComponent],
      bootstrap:    [ AppComponent ],
      providers:    [ { provide: RequestOptions, useClass: GlobalHttpOptions} ]
    })

    export class AppModule { }

কাজ করে না, নিজে চেষ্টা করে দেখি। রিফ্রেশ ছাড়া আর কিছুতে ডাকা হয় না।
ফিল

0

আমি একটি সহজ সমাধান চয়ন করতে সক্ষম হয়েছি> ডিফল্ট বিকল্পগুলিতে একটি নতুন শিরোনাম যুক্ত করুন আপনার এপিআই get (বা অন্যান্য) ফাংশন দ্বারা মার্জ বা লোড করুন।

get(endpoint: string, params?: any, options?: RequestOptions) {
  if (!options) {
    options = new RequestOptions();
    options.headers = new Headers( { "Accept": "application/json" } ); <<<<
  }
  // [...] 
}

অবশ্যই আপনি এই শিরোলেখগুলিকে ডিফল্ট বিকল্পগুলিতে বা আপনার শ্রেণীর যে কোনও কিছুতে বাহ্যিক করতে পারেন। এটি আয়নিক উত্পন্ন api.ts @ ইনজেক্টেবল () এক্সপোর্ট ক্লাসের API in in

এটি খুব দ্রুত এবং এটি আমার পক্ষে কাজ করে। আমি জেসন / এলডি ফর্ম্যাট চাইনি।


-4

আপনি canActiveআপনার রুটে যেমন ব্যবহার করতে পারেন :

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: AuthService, private router: Router) {}

  canActivate() {
    // If user is not logged in we'll send them to the homepage 
    if (!this.auth.loggedIn()) {
      this.router.navigate(['']);
      return false;
    }
    return true;
  }

}

const appRoutes: Routes = [
  {
    path: '', redirectTo: '/deals', pathMatch: 'full'
  },
  {
    path: 'special',
    component: PrivateDealsComponent,
    /* We'll use the canActivate API and pass in our AuthGuard.
       Now any time the /special route is hit, the AuthGuard will run
       first to make sure the user is logged in before activating and
       loading this route. */
    canActivate: [AuthGuard]
  }
];

থেকে নেওয়া: https://auth0.com/blog/angular-2- স্বীকৃতি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.