Я пытаюсь загрузить файл из интерфейса реакции на серверную часть C#. Я использую зону перетаскивания, чтобы получить файл, а затем я вызываю помощник api для публикации файла, но я получаю разные ошибки, когда пробую разные вещи. Я не уверен, какими должны быть заголовки и что мне следует отправлять, но получаю две разные ошибки. Если я не установил тип содержимого, я получаю ошибку 415 (неподдерживаемый тип носителя). Если я укажу тип содержимого как multipart / form-data, я получу внутреннюю ошибку сервера 500. Я получаю ту же ошибку, когда тип содержимого - application / json. URL вставлен, и я уверен, что он правильный. Я не уверен, следует ли добавлять файл как файл [0] [0], как я это сделал, или как файл [0], поскольку это массив, но я считаю, что он должен быть первым. Любые предложения приветствуются :) Вот мой вспомогательный код сообщения api:
export const uploadAdminFile = (file, path, method = 'POST', resource =
config.defaultResource) => {
const url = createUrl(resource, path);
const data = new FormData();
data.append('file', file[0][0]);
data.append('filename', file[0][0].name);
const request = accessToken =>
fetch(
url,
{
method,
mode: 'cors',
withCredentials: true,
processData: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json', //'multipart/form-data',
Authorization: `Bearer ${accessToken}`,
},
body: data,
})
.then(res => res.json())
.then(success => console.info('API HELPER: file upload success: ', success)
.catch(err => console.info('API HELPER: error during file upload: ', err)));
return sendRequest(request, resource);
};
Спасибо, я это понимаю. У меня нет доступа, чтобы сделать это в данный момент, поэтому я спрашиваю, может ли кто-нибудь помочь мне проверить / подтвердить, подтвердить или опровергнуть, что то, что я делаю, «правильно» / должно ли это работать на интерфейсе или есть что-то Я явно ошибаюсь
если вы пытаетесь загрузить файл, то, конечно, тип содержимого не будет JSON.
Однако более серьезная проблема, по-видимому, заключается в том, что свойство init в функции выборки не ожидает большинства имен свойств, которые вы там использовали. См. stackoverflow.com/questions/52162745/…. Вы не путаете его с jQuery $ .ajax (api.jquery.com/jquery.ajax) - для меня они похожи на параметры стиля jQuery. Также method должен быть method: "POST" или что-то в этом роде. Само по себе значение без имени бесполезно.
Они просто используют значения по умолчанию, поэтому мне не нужно их явно отправлять. А с синтаксисом ES ^ вы можете сократить key: value до одного значения, если имена совпадают, так что это то же самое, что и method: method,
Вы не используете значения по умолчанию для processData или withCredentials (хотя это не является прямым параметром root в любом случае, поэтому это неправильно, найдите его) или метода (параметры стиля jquery), ни для режима (параметр стиля выборки). Вы включаете в него довольно много нестандартных настроек, но вы смешиваете и сопоставляете параметры из двух разных библиотек, поэтому некоторые просто не распознаются функцией выборки и не будут применяться к сгенерированному HTTP-запросу. Решите, какую библиотеку вы хотите использовать, а затем правильно установите необходимые параметры в соответствии с соответствующей документацией.
Если вы не уверены, какие параметры установить, проконсультируйтесь с разработчиками API. Если у них нет явной документации, они, по крайней мере, должны быть в состоянии рассказать вам, как они ожидают структурирования HTTP-запроса, а затем вы сможете решить, какие параметры вызовут создание соответствующего запроса.
Какая часть кода - это jQuery?
Буквально нет jquery синтаксис. Я говорю, что "method", "withCredentials: true" и "processData: false" не являются допустимыми параметрами для метода fetch(), что ясно видно из документации. Однако по совпадению они (почти, в случае withCredentials) являются допустимыми параметрами для метода jQuery $ .ajax (), который также создает HTTP-запросы. Поэтому я предположил, что вы каким-то образом запутались между двумя функциями (fetch () и $ .ajax ()). Вы прочитали две ссылки, которые я вам дал? Откуда у вас возникла идея установить эти значения в функции fetch ()?
Я тоже прошу прощения - только что понял в моем предыдущем комментарии, я связался с вашим собственным вопросом, когда на самом деле я намеревался связать вас с документами fetch (): developer.mozilla.org/en-US/docs/Web/API/…
И моя общая точка зрения заключается в том, что тот факт, что вы предоставили параметры, которые на самом деле не работают, может способствовать вашей проблеме, если вы предполагаете, что они повлияют на способ создания HTTP-запроса.
На самом деле, извините, «метод» допустим в fetch (), но другие, о которых я упоминал, нет. Эта ссылка может оказаться вам полезной: stackoverflow.com/questions/36067767/…. Конечно, как я уже упоминал, вам также необходимо согласовать то, что вы делаете, с требованиями API.
Спасибо. Я видел этот пост. Сейчас я читаю документы, чтобы убедиться, что что-то из того, что я сделал, недействительно. Да, там есть код для тестирования и т. д., Но из того, что я вижу, я не использую никаких опций, которые недействительны для выборки. withCredentials действительно работает. Я не использую processData (это было то, что я пробовал из других ответов о переполнении стека.
И да, я видел другой ответ, который вы упомянули
если вы что-то не используете, удалите это. Какой вопрос предложил использовать ?? И для fetch () не задокументирована опция withCredentials. Вы уверены, что это имеет какой-то эффект? Не должно. Однако, если вы внимательно посмотрите на спецификацию fetch (), есть опция credentials. Однако он не принимает истинные или ложные значения. См. Также stackoverflow.com/questions/40543372/…. Я действительно не понимаю, почему вы продолжаете пробовать значения, которых нет в спецификации, только потому, что вы видели их в случайном вопросе SO.
Я попробовал все ваши предложения и удалил то, что вы определили. Я просто не обновлял здесь пример кода. Сейчас я думаю, что серверная часть может ожидать файловый поток, и мне нужно будет скрыть excel в json.
файловый поток - это не JSON. Отправка его в двоичном формате с использованием многостраничного кодирования ближе всего к «потоку» (что вы не можете сделать, используя HTTP таким образом). JSON - это текст. Если вы хотите отправить его в объекте JSON, вам придется закодировать его с помощью base64. Но вам действительно нужно проверить, что API на самом деле ожидает, а не гадать. Найдите его документацию или проконсультируйтесь с соответствующими людьми, которые его поддерживают.
Думаю, это часть проблемы: ссылка на сайт. Конечная точка ожидает Content-Type: multipart / form-data, однако граница все портит, но мне нужно иметь возможность отправлять accessToken в заголовке. Может быть, мне стоит попробовать другую библиотеку HTTP-запросов, например, axios, Request или superagent.
граница находится в теле запроса, токен доступа находится в заголовке. Я не понимаю, как они будут противоречить друг другу и насколько это действительно актуально. Вполне возможно отправлять заголовки с помощью составного запроса. Возможно, вам стоит заглянуть в инструменты вашего браузера, чтобы увидеть, как на самом деле выглядит окончательный запрос. Что, если вы просто полностью опустите заголовок contenttype?
Взгляните на ссылку, которую я опубликовал ... если вы опустите Content-Type, браузер добавит его обратно, а также добавит границу. Прочтите статью, и вы поймете, почему это важно.
Я понимаю, почему важна граница, но она не имеет ничего общего с заголовком авторизации. Я сделал небольшую демонстрацию здесь. jsfiddle.net/316txzhm/8 Это не идентично вашему коду, но есть самое необходимое с точки зрения того, как делается запрос. Выберите образец файла для загрузки и нажмите кнопку, а затем просмотрите свой запрос. Обратите внимание, что код не устанавливает заголовок типа содержимого, но он снова добавляется правильно с границей. Обратите внимание, что заголовок auth в порядке. Я также записал HTTP-запрос, сгенерированный браузером при его запуске (в Chrome): imgur.com/a/PntHs4L
AFAIK, это в основном правильный подход к загрузке как файла, так и его имени в отдельные поля в виде запроса, состоящего из нескольких частей. Ожидает ли ваша конечная точка чего-то еще? Граница необходима для того, чтобы конечная точка знала, где заканчиваются данные файла и начинаются данные имени файла. Если он не может с этим справиться, я не могу понять, как он сможет правильно читать требуемые данные. Кстати, вам действительно не нужно отправлять имя файла отдельно - обратите внимание, что запрос все равно включает его вместе с данными файла.



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


Спасибо за помощь и предложения, оказалось, что это проблема с серверной частью, но, тем не менее, я многому научился в процессе. Я опубликую здесь свой рабочий код на тот случай, если кто-нибудь столкнется с этим и сочтет его полезным.
export const uploadAdminFile = (file, path, resource=config.defaultResource) => {
const url = createUrl(resource, path);
const formData = new FormData();
formData.append('file', file[0][0]);
formData.append('filename', file[0][0].name);
const request = accessToken =>
fetch(url,
{
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: formData,
});
return sendRequest(request, resource);
};
Как уже упоминалось, имя файла не нужно отправлять отдельно и не указывать счетчик. Я индексирую файл таким образом, потому что я получаю его из dropzone в виде массива, и мне нужен только один файл (первый в массиве). Я надеюсь, что это поможет кому-то еще, и вот ссылка на mdn получить документы (хорошая информация) и хорошая статья по использованию fetch и formData.
«Я получаю внутреннюю ошибку сервера 500.» ... и вы исследовали причину этой ошибки? Это означает, что серверный код каким-то образом сломался. Вам необходимо отладить код сервера, изучить журналы и т. д., Чтобы выяснить, в чем заключалась фактическая ошибка.