簡體   English   中英

為什么我的Ajax帖子被截斷了?

[英]Why is my ajax post being truncated?

我剛剛更新了我的mvc服務,以包含更大的錯誤和日志記錄。 我現在已經多次遇到這個確切的錯誤。 但是無法復制。

Unterminated string. Expected delimiter: ". Path 'Breadcrumbs[18].Params', line 1, position 59740. at Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char quote) at 

每次路徑都不相同,具體取決於用戶向服務器發送的內容。

我的ajax請求通常如下所示:

$.ajax(myURL("SendBreadcrumbs"), {
            type: "POST",
            cache: false,
            data: { telemetry: telemetry.JSONify(), userID: currentUser, isMyVI: isMyVI }
        })

在這些情況下,userID和isMyVI(布爾值)不存在,並且遙測字符串被截斷。

JSONify方法如下:

self.JSONify = function () {
    var data = ko.mapping.toJSON(self, TelemetryMapping);
    return data;
}

這是基因敲除的序列化器。

服務器端:

public void SendBreadcrumbs(string telemetry, string userID = null, bool isMyVI = true)
{
    MyServiceAudit audit;
    Guid UserID;
    if (Guid.TryParse(userID, out UserID))
        audit = InsertAudit(UserID);
    else
        audit = InsertAudit(null);
    try
    {
        Models.Telemetry data = JsonConvert.DeserializeObject<Models.Telemetry>(telemetry);
        Controllers.Telemetry.UpdateTelemetry(data, isMyVI);
    }
    catch (Exception ex)
    {
         MyServiceAuditDB.FailAudit(audit.ID, ex.Message + " " + ex.StackTrace);
    }
}

我完全迷住了,我嘗試用更大的maxvalues等更新服務器上的web.config,以查看它在那一側被截斷了。

我的ajax唯一的其他區別是3分鍾的全局超時。

這是像在客戶端不處理特殊字符一樣簡單,還是在服務器端沒有限制,還是數據太大以致於被分塊並且服務器端不知道等待下一個塊?

我建議您使用提琴手來大致了解實際發送的數據。 當然,這是反序列化的問題,您的代碼看起來也很好。 數據的大小在這里不應該成為問題,獲取一些原始數據視圖就可以了。

另請參閱JSONify()是否返回正確格式化的數據而不轉義字符序列。

嘗試對用戶輸入的內容使用encodeURIComponent。

您沒有指定要使用哪個版本的jQuery,但是當我們假設一個穩定的版本時,我們可以確保$.ajax()下線中必要的編碼和轉義是完美的。

如果請求長度是原因,我們將在客戶端看到一個http錯誤,並且沒有調用服務器端函數(“超過最大請求長度”)。 您的觀察結果表明,較長的字符串請求可以成功,而較短的字符串可以失敗。

我建議采取以下兩種措施:

1)為減少碎片,分層和可能引起誤導的診斷,請勿僅對遙測進行JSON化。 根據遙測,userID和isMyVi構造您的對象,然后將作為整體進行JSON化(這意味着,如果可能,在TelemetryMapping描述中包括元數據)

2)在運行時客戶端檢查telemetry.JSONify()的值。 如果您發現截斷是由此引起的,請着重於基因敲除的版本和完整性,或者替換掉。 正如@Destrif在他們的評論中指出的那樣, https: //stackoverflow.com/a/21565447/1132334表示,轉義轉義雙引號,反斜杠和斜杠的任務可能不屬於敲除JS的任務-

這可能就像將調用包裝在另一個escape()一樣簡單:

self.JSONify = function () {
    var data = escape(ko.mapping.toJSON(self, TelemetryMapping));
    return data;
}

在一些評論,答案的幫助下,最后獲得了實時失敗的數據,我得以解決此問題。

事實證明,用戶不僅使用特殊字符,而且向下發送的一些靜態數據也包括這些字符(GIGO-無法相信我們某些數據的狀態)。

客戶端解決方案:

encodeURIComponent()函數對URI組件進行編碼。 此功能編碼特殊字符。 此外,它還對以下字符進行編碼:,/? :@&= + $#

$.ajax(myURL("SendBreadcrumbs"), {
        type: "POST",
        cache: false,
        data: { telemetry: encodeURIComponent(telemetry.JSONify()), userID: currentUser, isMyVI: isMyVI }
    })

服務器端解決方案:

將字符串轉換為其未轉義的表示形式。 Uri.UnescapeDataString()

public void SendBreadcrumbs(string telemetry, string userID = null, bool isMyVI = true)
{
    MyServiceAudit audit;
    Guid UserID;
    if (Guid.TryParse(userID, out UserID))
        audit = InsertAudit(UserID);
    else
        audit = InsertAudit(null);
    try
    {
        Models.Telemetry data = JsonConvert.DeserializeObject<Models.Telemetry>(Uri.UnescapeDataString(telemetry));
        Controllers.Telemetry.UpdateTelemetry(data, isMyVI);
    }
    catch (Exception ex)
    {
         MyServiceAuditDB.FailAudit(audit.ID, ex.Message + " " + ex.StackTrace);
    }
}

Web應用程序配置:

由於嘗試發送20封電子郵件,我的用戶遇到500錯誤。 我更新了配置,以包括最大請求長度(以千字節為單位,例如1GB)和最大內容長度(以字節為單位,例如1GB)。 電子郵件沒有問題。 簡直不敢相信!

<appSettings>
    <add key="aspnet:MaxJsonDeserializerMembers" value="150000" />
</appSettings>
<system.web>
    <httpRuntime targetFramework="4.5" maxQueryStringLength="32768" maxUrlLength="65536" maxRequestLength="1048576" />
</system.web>
<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxQueryString="32768" maxAllowedContentLength="1073741824"  />
        </requestFiltering>
    </security>
</system.webServer>
<system.web.extensions>
    <scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647" />
        </webServices>
    </scripting>
</system.web.extensions>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM