第二个答案,结合CORS问题,本地测试。
经过测试的 C# 代码(属性和ApiController):
[AttributeUsage(AttributeTargets.Method)]
public class AllowReferrerAttribute : ActionFilterAttribute
{
/// <summary>Update headers with CORS 'Access-Control-Allow-Origin' as required</summary>
/// <param name="actionContext">Context of action to work with</param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
var ctx = (System.Web.HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"];
var referrer = ctx.Request.UrlReferrer;
if (referrer != null)
{
string refhost = referrer.Host;
string thishost = ctx.Request.Url.Host;
if (refhost != thishost)
ctx.Response.AddHeader("Access-Control-Allow-Origin", string.Format("{0}://{1}", referrer.Scheme, referrer.Authority));
}
base.OnActionExecuting(actionContext);
}
}
public class TestController : ApiController
{
[AllowReferrer]
public void Post([FromBody]string value)
{
if (value == null)
throw new HttpResponseException(HttpStatusCode.BadRequest);
if (value.Length > 100000)
throw new HttpResponseException(HttpStatusCode.Forbidden);
}
}
要调用的 JavaScript 代码:
function imgToBase64(img)
{
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL('image/jpeg');
$(canvas).remove();
return dataURL;
}
$.ajax({ url: 'http://localhost:63905/api/Test', type: 'POST', data: "=" + imgToBase64($('img')[0]), crossDomain: true })
为了测试,我将上面的代码复制到浏览器的控制台中,并加载了一个外部页面(在我的一个服务器上),页面上的第一个图像是一个不错的大图像。数据按value 参数中的预期到达,并返回 403 错误,因为它的大小超过 100,000 个字节。
诀窍是:
您的 Post 处理程序中必须有一个 [FromBody] 参数。
传递给$.ajax 调用的数据必须是开头带有= 字符的字符串。这就是 ApiController 和 [FromBody] 的工作方式。 = 字符将被删除。
AllowReferrer 属性将阻止您的 JavaScript 代码在您尝试向其他站点执行 AJAX POST 时出错,但仅此而已。它只是阻止你向 JavaScript 报告你对它发布的数据做了什么。 POST 通常仍由您的控制器处理。
如果您所在的网站失败,可能是因为在提供图像时响应中出现了诸如 x-xss-protection:1; mode=block 之类的跨站点脚本标头。许多网站现在将这些标头设置为简单的 DNS 中毒攻击等的简单保护。这将导致如下错误:
SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
如果您收到该错误,则说明您遇到了 CORS 问题,您对此无能为力。如果您使用自己的代码,那么这不是问题,而是当您尝试从其他网站获取内容时,CORS 是一个问题。
不,我什至不会开始告诉你如何破解 CORS。这不是 Stack Overflow 的用途。