我在Azure和AngularJs
forntend上托管了HTTP request
后端。我了解有些OPTIONS request
使用预先核对OPTIONS requests
。我的问题是如何以这种方式实现后端,如果控制器中有一些将处理后续GET/POST/PUT/DELETE/...
的操作,则所有<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<style>
p{
height: 600px;
width: 600px;
font-size:17px;
}
</style>
</head>
<body>
<div ng-app="myApp" ng-controller="editor">
<label for="kys_font_size"> font size:</label>
<select ng-model="kys_selected_font" id="fontsize" name="kys_font_size" ng-options="page for page in FontSize(1, 150)" ng-change="changeFont()">
</select>
<p contenteditable="true" id="content" ng-change="print()" >
</p>
<input type="text" ng-model="name1">
<p >{{name1}}</p>
</div>
<p></p>
<script>
var app = angular.module('myApp',[]);
app.controller('editor',function($scope){
$scope.name1="jpos"
$scope.kys_selected_font = "hi there";
$scope.fonttext="hello";
$scope.FontSize = function(start, end) {
var size = [];
for (var i = start; i <= end; i++) {
size.push(i);
}
return size;
};
$scope.print= function(){
};
$scope.changeFont = function(){
$("#content").append("<b size='3' '> This is some text </b>");
$("#one").focus();
};
});
</script>
</body>
</html>
将返回200。
答案 0 :(得分:12)
解决此任务的非常优雅的方法是手动添加每个控制器
[AcceptVerbs("OPTIONS")]
public HttpResponseMessage Options()
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add("Access-Control-Allow-Methods", "GET,DELETE");
return resp;
}
或覆盖MessageHandlers
public class OptionsHttpMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Method == HttpMethod.Options)
{
var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
var controllerRequested = request.GetRouteData().Values["controller"] as string;
var supportedMethods = apiExplorer.ApiDescriptions.Where(d =>
{
var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName;
return string.Equals(
controller, controllerRequested, StringComparison.OrdinalIgnoreCase);
})
.Select(d => d.HttpMethod.Method)
.Distinct();
if (!supportedMethods.Any())
return Task.Factory.StartNew(
() => request.CreateResponse(HttpStatusCode.NotFound));
return Task.Factory.StartNew(() =>
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add(
"Access-Control-Allow-Methods", string.Join(",", supportedMethods));
return resp;
});
}
return base.SendAsync(request, cancellationToken);
}
}
然后在配置
GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHttpMessageHandler());
即便是第二种选择并不完美但是......没有本地支持
答案 1 :(得分:5)
我遇到了与您相同的问题,即所谓的Preflight请求,我发现这可能与Web.Conf文件上的错误配置有关。 注释掉或删除包含OPTIONSVerbHandler“删除”的行(如果存在)。
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
var sharedFolder = Path.Combine(env.ContentRootPath, "..", "Shared");
config
.AddJsonFile(Path.Combine(sharedFolder, "SharedSettings.json"), optional: true) // When running using dotnet run
.AddJsonFile("SharedSettings.json", optional: true) // When app is published
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
config.AddEnvironmentVariables();
})