默认情况下ajax请求是有同源策略,限制了不同域请求的响应。

例子:http://localhost:23160/HtmlPage.html 请求不同源API http://localhost:22852/api/values,

What is "Same Origin"?

Two URLs have the same origin if they have identical schemes, hosts, and ports. (RFC 6454)

These two URLs have the same origin:

  • http://example.com/foo.html
  • http://example.com/bar.html

These URLs have different origins than the previous two:

  • http://example.net - Different domain
  • http://example.com:9000/foo.html - Different port
  • https://example.com/foo.html - Different scheme
  • http://www.example.com/foo.html - Different subdomain

http://localhost:23160/HtmlPage.html 代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function () {
$("#Button1").click(function () {
$.ajax({
url: "http://localhost:22852/api/values",
success: function (data) {
alert(data);
}
});
});
});
</script>
</head>
<body>
<input id="Button1" type="button" value="button" />
</body>
</html>

通过调试我们发现,ajax请求成功发送到API,API后台的断点走到了,并且返回了数据,并没有什么问题。 在web端,查看网络,显示的status状态也是200,但是响应的内容却是空的。

这时,查看控制台会发现错误:XMLHttpRequest cannot load http://localhost:22852/api/values. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:23160' is therefore not allowed access.

提示API响应头中没有‘Access-Control-Allow-Origin'头,标识可以允许源http://localhost:23160访问。

我们发现,同源策略,并没有阻止请求的发送,但是阻止了,不同源请求的响应。

如何对指定的源,开放访问?

微软的工程师已经给出了解决方案,直接在安装一个现成的package就能解决。

1.add the CORS NuGet package. In Visual Studio, from the Tools menu, select Library Package Manager, then select Package Manager Console. In the Package Manager Console window, type the following command:

Install-Package Microsoft.AspNet.WebApi.Cors  

This command installs the latest package and updates all dependencies, including the core Web API libraries. User the -Version flag to target a specific version. The CORS package requires Web API 2.0 or later.

2.Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method.

using System.Web.Http;
namespace WebService
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// enable cors
config.EnableCors(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

3. Next, add the [EnableCors] attribute to the TestController class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors; namespace ServerSide.Controllers
{
[EnableCors(origins: "http://localhost:23160", headers: "*", methods: "*")]
public class TestController : ApiController
{
public HttpResponseMessage Get()
{
return new HttpResponseMessage()
{
Content = new StringContent("GET: Test message")
};
}
}
}

经过以上3个步骤,在web端调用API后,成功获取响应内容:”GET: Test message“

详细请参考:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

我走的弯路:

1.可能是VS2013的原因,安装了Microsoft.AspNet.WebApi.Cors包之后,生成成功,运行的时候,报错:未能加载文件或程序集“System.Web.Http”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。我一看,是因为引用的版本不一致,但是packages中和Bin中都是存放的最新的5.2.3版本的,只是却报错说找不到5.0.0版本,很奇怪,5.0.0版本是安装Cors包之前版本,安装cors包会把依赖的system.web.http自动升级到5.2.3,把l5.0.0的老版本删掉了。为什么还是报这个错误。而且很奇怪的是,web.config中并没有dll引用的配置,package.config中也没有,以前.net项目,dll的版本维护都是在web.config中,难道WebAPI换了方式,那是怎么配置的呢,网上也没有找到答案,后来我查看我本地其它API项目,发现dll是在web.config中配置的呀。 于是尝试按照其它项目一样,在webconfig中configuration根目录添加runtime阶段配置assemblyBinding,指定5.2.3版本的dll,成功解决问题,web.config代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<appSettings>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web> <system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime> </configuration>

2.上面的问题解决后,忘记了在App_Start/WebApiConfig.cs中添加配置,仅仅在Controller类上添加了attribute,还是不能跨源访问,以为是我VS哪里出问题了,我的版本是VS2013,作者是VS2013 Update2,又尝试去升级。最后重新走一遍流程,才发现遗漏配置了,添加配置后,终于能够跨源请求,正确获取响应了。

As.net WebAPI CORS, 开启跨源访问,解决错误No 'Access-Control-Allow-Origin' header is present on the requested resource的更多相关文章

  1. Webapi 跨域 解决解决错误No 'Access-Control-Allow-Origin' header is present on the requested resource 问题

    首先是web端(http://localhost:53784) 请求 api(http://localhost:81/api/)时出现错误信息: 查看控制台会发现错误:XMLHttpRequest c ...

  2. java、ajax 跨域请求解决方案('Access-Control-Allow-Origin' header is present on the requested resource. Origin '请求源' is therefore not allowed access.)

      1.情景展示 ajax调取java服务器请求报错 报错信息如下: 'Access-Control-Allow-Origin' header is present on the requested ...

  3. js跨域访问,No 'Access-Control-Allow-Origin' header is present on the requested resource

    js跨域访问提示错误:XMLHttpRequest cannot load http://...... No 'Access-Control-Allow-Origin' header is prese ...

  4. WCF REST开启Cors 解决 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. The response had HTTP status code 405.

    现象: 编写了REST接口: [ServiceContract] public interface IService1 { [OperationContract] [WebInvoke(UriTemp ...

  5. .Net Core 处理跨域问题Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

    网页请求报错: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Or ...

  6. 解决跨域No 'Access-Control-Allow-Origin' header is present on the requested resource.

    用angular发起http.get(),访问后端web API要数据,结果chrome报错:跨域了 Access to XMLHttpRequest at 'http://127.0.0.1:300 ...

  7. (转)AJax跨域:No 'Access-Control-Allow-Origin' header is present on the requested resource

    在本地用ajax跨域访问请求时报错: No 'Access-Control-Allow-Origin' header is present on the requested resource. Ori ...

  8. ajax跨域(No 'Access-Control-Allow-Origin' header is present on the requested resource)

    问题 在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题.另一个域名必须在response中添加 Access-Control-Allow-Origin 的header,才能让前者成功 ...

  9. 跨域问题解决----NO 'Access-Control-Allow-Origin' header is present on the requested resource.Origin'http://localhost:11000' is therfore not allowed access'

    NO 'Access-Control-Allow-Origin' header is present on the requested resource.Origin'http://localhost ...

随机推荐

  1. IE11-IE不再任性了-关于attachEvent

    今天解决了一个IE11的兼容问题,关于attachEvent的. 控件是ActiveX的,需要监听一个控件相关的事件.蓦然发现attachEvent在IE11不支持了...attachEvent不是I ...

  2. 关于Oracle的rac集群和mysql Galera Cluster的想法

    到了新公司,公司用的是rac,我比较熟悉mysql第三方的集群方案Galera Cluster这类多主集群, 下面是我参考了他人对rac的介绍,然后和mysql方案进行的臆测级别的分析对比. rac和 ...

  3. select修改原生样式组件

    <div class="select"> <select class="" name=""> <option ...

  4. Linux下yum安装MPlayer 或 LVC视频播放器

    添加第三方源 su -c 'rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noar ...

  5. leetcode 36

    36. Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudok ...

  6. Velocity语法大全

    1\ 参考地址:http://www.cnblogs.com/codingsilence/archive/2011/03/29/2146580.html

  7. C++ sstream 中处理字符串

    C++引入ostringstream.istringstream.stringstream这三个类,要使用他们创建对象就必须包含<sstream>这个头文件. istringstream的 ...

  8. getComputedStyle(and currentStyle)

    1.getComputedStyle 1.1 用法: currentStyle获取计算后的样式,也叫当前样式.最终样式.优点:可以获取元素的最终样式,包括浏览器的默认值,而不像style只能获取行间样 ...

  9. 分享:php 上传图片的代码

    转自:http://www.jbxue.com/article/6379.html php 上传图片的代码,很简单,实现了基本的文件类型.文件大小的检测,并实现了基本的水印与缩略功能,比较适合初学的朋 ...

  10. PHP通过IP 获取 地理位置(实例)

    发布:JB02   来源:脚本学堂  分享一例php代码,实现通过IP地址获取访问者的地理位置,在php编程中经常用到,有需要的朋友参考下吧.本节内容:PHP通过IP获取地理位置 例子: 复制代码代码 ...