【问题标题】:How to do AJAX POST cross-domain with custom headers如何使用自定义标头进行 AJAX POST 跨域
【发布时间】:2017-05-16 03:14:54
【问题描述】:

我一直在四处寻找,但我找不到明确的答案。

我需要能够执行 AJAX POST 并发送自定义标头。我可以完全控制客户端脚本和服务器端服务,所以如果我必须对任何一方进行任何调整以使其正常工作,我都可以进行这些更改。

我目前正在使用 jQuery,但是如果 jQuery 无法做到这一点,我需要使用另一个完全没有问题的库。理想情况下,我宁愿坚持使用单个库 (jQuery),但如果它解决了我的问题,我非常乐意使用第二个。

目前我的代码如下所示:

$.ajax({
    type: 'POST',
    url: 'http://localhost:65079/TestHandler',
    crossDomain: true,
    data: myVariableOfData,
    dataType: 'json',
    beforeSend: function(xhr) {
        xhr.setRequestHeader('MessageId', 'abc123');
    },
    success: function(responseData, textStatus, messageId) {
        console.log("success");
    },
    error: function(responseData, textStatus, errorThrown) {
        console.log(textStatus);
        console.log(responseData);
        console.log(errorThrown);
    }
});

不幸的是,jQuery 甚至没有尝试将请求发送到服务器,但是一旦我删除了标头,它就会发送请求。不过,我真的需要这些标题,因此我们将不胜感激。

请向我提出任何可能有助于解决此问题的问题,我会尽快回复。

【问题讨论】:

  • Afaik jQuery 拒绝在跨域请求上设置标头,因为并非所有浏览器都兼容 - 如果 IE 不支持某个功能,jQuery 通常会禁用它
  • @Bergi 正如我所提到的,我不需要坚持使用 jQuery,我需要支持的唯一浏览器是当前的堆栈(IE9+、最新的 Chrome 和最新的 Firefox) - 你知道我该怎么做吗?不用 jQuery 也能解决这个问题?
  • 你能在TestHandler分享你的标题吗?
  • 如果你的意思是我在网络服务上的代码,那么看看这里的 Global.asax.cs 代码:dotnet-tricks.com/Tutorial/wcf/… - 这就是我的(但我没有做WCF)

标签: javascript jquery ajax cross-domain


【解决方案1】:

我不知道你是否还在寻找一种方法来做到这一点。这是可以做到的。这是一个示例 CORS 处理程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Api.Handlers
{
    /// <summary>
    /// 
    /// </summary>
    public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;

            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                    response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                    string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                    if (accessControlRequestMethod != null)
                    {
                        response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                    }

                    string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                    if (!string.IsNullOrEmpty(requestedHeaders))
                    {
                        response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                    }

                    TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
                    tcs.SetResult(response);
                    return tcs.Task;
                }

                return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
                {
                    HttpResponseMessage resp = t.Result;
                    resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                    return resp;
                });
            }

            return base.SendAsync(request, cancellationToken);
        }
    }
}

添加后,在 Application_Start 方法内的 Global.asax 文件中注册处理程序

GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());

现在您可以发送请求标头了。希望有帮助。这已经通过 Web API、MVC 4 以及来自 Google Chrome 和 Firefox 的站点进行了测试。

【讨论】:

    【解决方案2】:

    冒着听起来完全像 Siri 的风险,听起来像是在寻找如何让 CORS 工作......

    以下是一些希望能有所帮助的资源:

    【讨论】:

    • 这些问题中的哪个处理请求标头?
    • 我实际上已经有 CORS 工作,这就是我的 POST 请求在没有标头的情况下的工作方式。您提供的链接都没有演示如何发送自定义标头(至少从我所见)。
    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 2016-10-05
    • 2019-03-09
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多