Angular Cross-Origin请求已被阻止

时间:2018-04-26 10:50:56

标签: angular firefox http-headers cross-domain

我在Angular CLI中遇到Http请求问题。我不知道如何解决这个问题。是因为localhost,还是浏览器设置,还是openwethermap服务?有可能解决这个问题吗?但是,当我使用ng build命令构建应用程序时,它可以正常工作。

日志警告将在控制台中打印出来:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the
remote resource at http://api.openweathermap.org/data/2.5/forecast?lat=35&
lon=139&appid=<my_api_key_is_removed_on_stackoverflow>. (Reason: CORS preflight
channel did not succeed).

app.module.ts:

/* Core */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

/* Components */
import { AppComponent } from './app.component';
import { FixtureComponent } from './soccer/fixture.component';
import { WeatherComponent } from './weather/weather.component';

/* Interceptors */
import { SoccerAuthInterceptor } from './soccer/soccer.interceptor';

/* Services */
import { WeatherService } from './weather/weather.service';

@NgModule({
  declarations: [
    AppComponent,
    FixtureComponent,
    WeatherComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    WeatherService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: SoccerAuthInterceptor,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

weather.servece.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';

interface Weather {
  message: Number;
  temp: Number;
  temp_min: Number;
  temp_max: Number;
  /* teasdmp: Array<string>; */
}
@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  constructor(private http: HttpClient) { }
  dailyForecast(): Observable<Weather> {
    return this.http.get<Weather>("http://api.openweathermap.org/data/2.5/forecast?lat=35&lon=139&appid=<api_key>").pipe(map(result => result));
  }

  /* private apiUrl = "http://localhost:3000/api/cars";
  getCars(): Observable<Car[]> {
    // tell Angular you are expecting an array of 'Car'
    return this.httpClient.get<Car[]>(this.apiUrl)
  } */
}

weather.component.ts:

import { Component } from '@angular/core';
import { WeatherService } from './weather.service';
import { Chart } from 'chart.js';

@Component({
  selector: 'app-weather',
  template: `
    <div *ngIf="chart">
      <canvas id="canvas">{{ chart }}</canvas>
    </div>`,
  styles: []
})

export class WeatherComponent {

  chart = []; // This will hold our chart info

  constructor(private _weather: WeatherService) { }

  ngOnInit() {
    console.log('test');
    console.log(this._weather.dailyForecast());
    this._weather.dailyForecast()
    .subscribe(res => {
      console.log(res);
      let temp_max = res['list'].map(res => res.main.temp_max);
      let temp_min = res['list'].map(res => res.main.temp_min);
      let alldates = res['list'].map(res => res.dt)

      let weatherDates = []
      alldates.forEach((res) => {
        let jsdate = new Date(res * 1000)
        weatherDates.push(jsdate.toLocaleTimeString('en', { year: 'numeric', month: 'short', day: 'numeric' }))
      })
      this.chart = new Chart('canvas', {
        type: 'line',
        data: {
          labels: weatherDates,
          datasets: [
            {
              data: temp_max,
              borderColor: "#3cba9f",
              fill: false
            },
            {
              data: temp_min,
              borderColor: "#ffcc00",
              fill: false
            },
          ]
        },
        options: {
          legend: {
              display: false
            },
            scales: {
              xAxes: [{
                display: true
              }],
              yAxes: [{
                display: true
              }],
            }
          }
        });
      })
  }
}

也许这就是问题所在?但如果是这样,为什么在我运行命令ng build

时它会起作用
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

export class SoccerAuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authReq = req.clone({
      headers: req.headers.set('X-Auth-Token', '<api_key>')
    });
    return next.handle(authReq);
  }
}

1 个答案:

答案 0 :(得分:1)

如果您遇到跨域问题,可能是浏览器抱怨访问的资源与应用程序所在的路径不同(我想您不会在openweathermap工作并主持.org)您需要运行自己的代理服务器转发请求http://api.openweathermap.org并设置标头,以便您从中托管客户端。例如,您可以使用SpringBoot和Netlix Zuul代理库执行此操作。