【问题标题】:Remove 'X-Requested-With' from query string url during ajax request在 ajax 请求期间从查询字符串 url 中删除“X-Requested-With”
【发布时间】:2016-09-03 09:41:45
【问题描述】:

我遇到的问题是&X-Requested-With=XMLHttpRequest&_=1462736803425 一直被附加到我的网址,因为它是查询字符串的一部分。有没有办法可以阻止它成为查询字符串并在不执行“hack”的情况下执行Ajax.BeginForm

@using (Ajax.BeginForm("Search", "Filter", new { Area = "Music" }, new AjaxOptions { HttpMethod = "Get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "body-wrapper", OnSuccess = "updateHistory" }, new { @id = "search-form" }))
{
       <div>
           <i class="fa fa-search"></i>
           <input type="search" placeholder="Search" id="search" name="searchString" />
       </div>
}

public ActionResult Search(string searchString)
{
    //do stuff
    return PartialView();
}

然后我在部分视图页面上获取路径和查询:

@Html.HiddenFor(x => Request.Url.PathAndQuery)

Request.Url.PathAndQuery 的值为:http://localhost:1526/Music/Search?searchString=maid&amp;X-Requested-With=XMLHttpRequest&amp;_=1462736803425

然后使用 History.js 更新 url:

function pushState(target) {
    manualStateChange = false;
    History.pushState(null, null, $("#Request_Url_PathAndQuery").val());
}

【问题讨论】:

    标签: javascript c# jquery ajax asp.net-mvc


    【解决方案1】:

    不更改"jquery-ajax-unobtrusive.js" 的源文件,这并不容易。这里的问题在第 117 行:

    options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
    

    它在发送请求之前添加该数据。这有点令人讨厌,尤其是在我看来,该值应该是 HTTP 标头,而不是数据的一部分。

    可能可以通过在表单的 ajax 请求中添加 beforeSend 选项来删除它。也就是说,你想定义一个函数:

    function removeExtraData(jqXHR, settings) {
      if (settings.data.hasOwnProperty('X-Requested-With')) {
        delete settings.data['X-Requested-With']; // or settings.data['X-Requested-With'] = undefined;
      }
    }
    

    然后您可以通过在表单中​​添加一个值为removeExtraDatadata-ajax-begin HTML 属性来使用它。我还没有验证过,而且我使用 WebForms 已经有几年了,所以我没有要测试的设置。

    URL 的_=1462736803425 部分由jQuery 自动附加,因为请求被设置为不被缓存。显然,您可以通过在表单中​​添加名称为data-ajax-cache 和值true 的HTML 属性来摆脱这种情况。当然,这最终可能会缓存您的请求,这可能是不可取的。

    【讨论】:

    • 感谢您的回答,解决了一些问题。 settings 没有 data 的属性,我找不到要删除的标题。
    • 我能想到的唯一其他方法是不使用Ajax.BeginForm。使用Html.BeginForm 直接使用jQuery 用ajax 提交表单。不过,这是相当多的工作。
    • 感谢您的帮助。真的很烦人,这甚至是使用 ajax 助手的问题。如果没有更好的答案,我稍后会给你赏金。
    【解决方案2】:

    我认为你可以通过覆盖 url 路径来解决这个问题。

    在 Application_BeginRequest() 中,您可以检查所需的任何条件并使用 context.RewritePath() 并删除不必要的参数。

    类似这样的:

        protected override void Application_BeginRequest(object sender, EventArgs e)
        {
            base.Application_BeginRequest(sender, e);
            var urlpath = HttpContext.Current.Request.Url.PathAndQuery; //Modify this based on condition
            if(<condition>)
                Context.RewritePath(<updatedpath>);
        }
    

    这可能会解决您的问题,但我不能说这是否是一个好方法。

    【讨论】:

    • 这是 MVC 管道中的一个方法。如果你没有自定义实现,你可以直接使用它,因为它也调用基函数。
    【解决方案3】:

    我所采用的是这个,虽然它是一种 hack 并且不是真正可取的,所以如果有人找到更好的方法,请说。它从 url 中删除查询字符串参数,它之所以有效,是因为 xhr 总是附加在末尾。

    function pushState(target) {
        //Remove the queryString parameter of xhr that gets appened in 117 of ajax-unobtrusive.js
        var index = target.indexOf("?X-Requested-With");
        if (index === -1) 
            index = target.indexOf("&X-Requested-With");
    
        target = target.replace(target.substring(index), "");
    
        manualStateChange = false;
        History.pushState(null, $("input#Title").val(), target);
    }
    

    编辑。基于 Mike 评论的新答案:

    @using (Html.BeginForm("Index", "Search", new { area = "Media" }, FormMethod.Get, new { @id = "search", data_url = Url.Action("SetSearchTags", "Search", new { Area = "Media" }) }))
    {
        <i class="fa fa-search"></i>
        <input type="search" placeholder="Search" id="search" name="searchString" />
    
        <div id="filter" name="filter">
            <span><strong>Syntax</strong></span>
    
            @foreach (var item in SearchContext.SearchFilters)
            {
                <div id="filter-@item">
                    @Html.DisplayFor(x => item)
                </div>
            }
        </div>
    }
    
    $("form#search").submit(function (event) {
        event.preventDefault();
    
        var $form = $(this);
        var searchString = $form.find("input[type='search']").val();
        var url = $form.attr("action");
        var method = $form.attr("method");
    
        $.ajax({
            url: url,
            data: { searchString: searchString },
            method: method,
            success: function (data) {
                $('#body-content').html(data);
                updateHistory(true);
            }
        });
    });
    
    function updateHistory(useQuery) {
        var path = (useQuery === true) ? $("#Request_Url_PathAndQuery").val() : $("#Request_Url_AbsolutePath").val();
    
        pushState(path);
    };
    

    基本上,只要我需要查询字符串参数,我只需要在 jquery 中手动完成,而不是使用帮助器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2020-01-29
      • 2011-02-02
      • 1970-01-01
      相关资源
      最近更新 更多