Я работаю над устаревшей системой и ищу способы повышения производительности. Это проект MVC с серверной частью C# (обновленной до .net 8) и интерфейсом Javascript/JQuery. Код внешнего интерфейса использует AJAX для выполнения вызовов, и все работает нормально, но я пытаюсь переключить его на использование Fetch и наткнулся на кирпичную стену. Все процедуры на стороне сервера используют следующий стиль:
public IActionResult SearchCerts(string Company, string ExpStart, string ExpEnd)
{
...
return PartialView("_SearchResults", Results);
}
и они вызываются с помощью:
function SearchCerts() {
$.ajax({
url: "/Certs/SearchCerts",
data: {
Company: document.getElementById("edtSearchCompany").value,
ExpStart: document.getElementById("edtSearchExpires1").value,
ExpEnd: document.getElementById("edtSearchExpires2").value
},
dataType: "html",
async: true,
success: function (data, textStatus, XMLHttpRequest) {
$('#divSearchResults').html(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Error");
}
});
}
Когда я пытаюсь использовать Fetch, все параметры оказываются нулевыми, и единственный способ передать что-либо — это обновить подпрограмму на стороне сервера, чтобы она принимала параметр IFormCollection (извлекая отдельные значения при необходимости) и передайте переменную FormData следующим образом:
async function SearchCertsExecute() {
var formData = new FormData();
formData.append('Company', document.getElementById("edtSearchCompany").value);
formData.append('ExpStart', document.getElementById("edtSearchExpires1").value);
formData.append('ExpEnd', document.getElementById("edtSearchExpires2").value);
let Results = await fetch("/Certs/SearchCerts", {
method: 'POST',
body: formData
});
if (Results.ok) {
var data = await Results.text();
$('#divSearchResults').html(data);
} else {
alert("HTTP-Error: " + Results.status);
}
}
Я попытался создать объект Javascript, содержащий, а затем использовать JSON.stringify, но сервер все равно не получает ничего, кроме нулей:
var SendData = {
Company: document.getElementById("edtSearchCompany").value,
ExpStart: document.getElementById("edtSearchExpires1").value,
ExpEnd: document.getElementById("edtSearchExpires2").value
};
let Results = await fetch("/Certs/SearchCerts", {
method: 'POST',
body: JSON.stringify(SendData)
});
Может ли кто-нибудь пролить свет на то, что мне не хватает?
Кроме того, вы можете попробовать использовать какой-нибудь инструмент мониторинга запросов, например Surfshark или Fiddler Telerik, чтобы проанализировать различия между двумя http-вызовами.
@Ivar Только что попробовал переключить Fetch, чтобы указать GET и Javascript, вылетает: Не удалось выполнить «fetch» в «Window»: запрос с методом GET/HEAD не может иметь тело.
@TheNeil Верно. GET-запросы не могут иметь тело в JavaScript. jQuery автоматически меняет тело на параметры URL, но fetch не делает этого за вас, поэтому вам нужно сделать это вручную.
@Ivar Посмотрев, что на самом деле было отправлено с использованием двух разных методов (как было предложено), я увидел, что AJAX добавил данные в качестве параметров URL-адреса, и у меня возникло ужасное ощущение, что мне придется делать это вручную с помощью Fetch. Я понятия не имел, что JQuery «помогает» - спасибо за понимание =:)
@FernandoDelCantão или просто откройте инструменты разработки браузера и посмотрите вкладку «Сеть». 1. быстрее 2. встроенный.
@TheNeil «было ужасное ощущение, что мне придется делать это вручную с помощью Fetch». вам не обязательно. Вы можете просто использовать URL + URLSearchParams, которые сделают всю работу по созданию действующего URL-адреса за вас: Установка строки запроса с помощью запроса Fetch GET



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я опубликую это как ответ из-за кода
попробуйте сделать выборку следующим образом:
fetch("/Certs/SearchCerts", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
Company: document.getElementById("edtSearchCompany").value,
ExpStart: document.getElementById("edtSearchExpires1").value,
ExpEnd: document.getElementById("edtSearchExpires2").value
})
})
.then(response => response.text())
.then(data => {
document.getElementById('divSearchResults').innerHTML = data;
})
.catch(error => {
alert("Error");
});
В C# MVC типом контента по умолчанию для запроса POST является application/x-www-form-urlencoded. В вашем примере выборки js значением по умолчанию является multipart/form-data.
Это должно сработать.
Это сработало отлично - просто тип контента был неправильным. Спасибо, спасибо, спасибо =:)
Ваша версия jQuery, похоже, отправляет запрос GET (это значение по умолчанию, если у вас нет свойства
typeилиmethod), а ваша версияfetchвыполняет запрос POST. Для запросов GET$.ajax()добавляет тело к URL-адресу (в качестве параметров строки запроса). (Я не эксперт по .NET, поэтому не знаю, имеет ли это значение.)