我在使用Windows身份验证的远程服务器上的IIS 7上托管了.net web api。我想使用带有节点的TypeScript,使用 Angular 2访问web api。早些时候我收到错误'对预检请求的响应没有通过访问控制检查:请求的资源上没有'Access-Control-Allow-Origin'标题'
我在托管应用程序的web.config
上添加了这个<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
但现在我收到了未经授权的401错误。我已经阅读了有关添加以下代码以允许跨域访问的内容 - 但我不知道我在角色2应用程序中添加它以及如何编译。
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/', function(req, res, next) {
// Handle the get for this route
});
app.post('/', function(req, res, next) {
// Handle the post for this route
});
以下是我尝试使用
进行get调用的服务示例代码@Injectable()
export class TodoService {
todos$: Observable<Todo[]>;
private _baseUrl: string;
private _todosObserver: Observer<Todo[]>;
private _dataStore: {
todos: Todo[]
};
constructor(private _http: Http) {
//let headers: Headers = new Headers();
this._baseUrl = 'http:/SampleServer/Server/api/LoadTodo';
this.todos$ = new Observable(observer => this._todosObserver = observer).share();
this._dataStore = { todos: [] };
}
loadTodos() {
let headers: Headers = new Headers();
//headers.append('Access-Control-Allow-Origin');
headers.append('Authorization', 'Basic ' +
btoa('username:password'));
//let opts: RequestOptions = new RequestOptions();
//opts.headers = headers;
this._http.get(`${this._baseUrl}`,headers).map(response => response.json()).subscribe(data => {
this._dataStore.todos = data;
this._todosObserver.next(this._dataStore.todos);
}, error => console.log('Could not load todos.'));
}
解决此问题的任何帮助都会很棒。
答案 0 :(得分:1)
您需要检查请求中是否正确发送了Authorization
标头。如果您忘记导入Headers
类,则不会发送标题:
import {Http, Headers, ...} from 'angular2/http';
另一种选择是,由于您处于预检请求(带有Authorization
标头的GET方法),因此会发送OPTIONS请求。实际上,此请求由浏览器透明地发送,并且凭证存在于其中。因此,您不必在服务器端检查安全性。否则您将遇到401错误,因为服务器无法验证请求...
有关详细信息,请参阅这些文章:
答案 1 :(得分:1)
在ASP.NET Core解决方案中使用Angular 2时,我偶然发现了同样的问题。对我来说,我明确指定了withCredentials: true
:
getSomeModels() {
return this.http.get(this.apiBasePath + 'models', { withCredentials: true })
.map(res => res.json());
}
必须在服务器端(Web API)启用CORS,并且客户端不需要进行其他更改。
注意:启用CORS(Startup.cs)的服务器端代码
public void ConfigureServices(IServiceCollection services)
{
// injected services
services.AddAuthorization();
services.AddMvc();
//db context
var corsBuilder = new CorsPolicyBuilder();
corsBuilder.AllowAnyHeader();
corsBuilder.AllowAnyMethod();
corsBuilder.AllowAnyOrigin(); // For anyone access.
corsBuilder.AllowCredentials();
services.AddCors(options =>
{
options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// middleware configuration
app.UseCors("SiteCorsPolicy");
}