представлять
В сценарии разработки, когда интерфейс и сервер разделены, неизбежна совместная отладка интерфейса и сервера. На этапе совместной отладки часто встречаются различные проблемы, такие как искажение символов, данные (строки, массивы, Json-объекты), передаваемые с фронтенда, не могут быть нормально разобраны на бэкенде и т.д.
В этой статье мы надеемся начать с первоисточника, прояснить первопричину проблемы, быстро определить местонахождение проблемы, сделать удобной регулировку переднего и заднего шарнира и упростить сброс горшка. .
HTTP-протокол
Причина, по которой здесь будет представлен протокол HTTP, заключается в том, что совместная отладка интерфейса и сервера неотделима от HTTP. Понимание протокола HTTP поможет вам лучше понять процесс передачи данных, а также лучше проанализировать, в чем заключается проблема, что удобно для устранения неполадок.
1. Введение
Прежде всего, http — это протокол без сохранения состояния, то есть каждое взаимодействие клиента и сервера не имеет состояния, обычно с использованием файлов cookie для сохранения состояния.
На следующем рисунке показана общая структура http-запросов и ответов (все изображения в этой части взяты из "HTTP Authoritative Guide"):
проиллюстрировать:
Как видно из рисунка выше, HTTP-запрос условно делится на три части: стартовая строка, заголовок и тело. В строке запуска запроса указывается способ запроса, адрес запроса и версия http-протокола. Кроме того, первая часть — это то, что мы часто называем заголовком http.
2. HTTP method
Следующие часто используемые методы HTTP-запросов и их введение:
проиллюстрировать:
- Обычно мы используем get in post.
- Включать ли тело означает, имеет ли содержимое запроса тело. Например, в методе get из-за отсутствия тела для передачи параметров можно использовать только метод url.
3. Content-type
Тип контента и кодировка HTTP-передачи контролируются Content-Type, и клиент и сервер используют его для идентификации и анализа передаваемого контента.
Общий тип содержимого:
Типы | иллюстрировать |
---|---|
text/html | тип html |
text/css | css-файл |
text/javascript | js-файл |
text/plain | текстовый файл |
application/json | json-тип |
application/xml | XML-тип |
application/x-www-form-urlencoded | form, тип по умолчанию при отправке формы |
multipart/form-data | Тип вложения, обычно форма загрузки файла |
Первые шесть являются распространенными типами файлов, а последние два — типами, когда данные формы отправляются. Когда мы отправляем данные через ajax, обычноContent-Type:application/x-www-form-urlencoded;charset=utf-8
, который объявляет формат данных и метод кодирования данных этого запроса. Следует отметить, что этот тип application/x-www-form-urlencoded является особым, при отправке данных данные формы будут склеены во что-то похожее наa=1&b=2&c=3
Формат, если пробелы или специальные символы существуют в данных, он преобразует стандартный документздесь, подробнее в[RFC1738]видимый.
Релевантная информация:
- Таблица сравнения типов контента:tool.oschina.net/commons
- Типы содержимого формы:Я 3.org/TR/HTML4/in…
- Исследование проблемы декодирования знака плюс в пробел при декодировании символов:много Study.com/2017/12/06/…
- Понимание типа содержимого HTTP:дорога домой.?/2015/07/19/…
4. Набор символов и кодировка
Причина, по которой вам необходимо понимать эту часть совместной отладки внешнего и внутреннего интерфейса, заключается в том, что при взаимодействии данных между внешним и внутренним интерфейсом вы часто сталкиваетесь с проблемой искаженных символов. содержание, вы можете легко решить проблему искаженных символов.
Одна картинка стоит тысячи слов:
На рисунке значение charset равноiso-8859-6
, в котором подробно описывается полный процесс текста от кодирования до декодирования для отображения.
Релевантная информация:
- Список наборов символов:Woohoo.IANA.org/assignments…
- Детали кодировки символов:много Study.com/2016/08/26/…
внешний интерфейс
Внешняя часть отвечает за инициирование HTTP-запросов.В интерфейсе обычно используются классы инструментов HTTP-запросов:jquery
,axios
,fetch
. Фактически используется нижний слой jquery и axiosXMLHttpRequest
Чтобы инициировать http-запрос, fetch относится к встроенному в браузер методу инициирования http-запроса.
Пример внешнего запроса ajax:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.5.1/qs.min.js"></script>
<title>前端发起HTTP请求样例</title>
</head>
<body>
<h2>使用XMLHttpRequest</h2>
<button onclick="xhrGet()">XHR Get</button>
<button onclick="xhrPost()">XHR Post</button>
<h2>使用axios</h2>
<button onclick="axiosGet()">Axios Get</button>
<button onclick="axiosPost()">Axios Post</button>
<h2>使用fetch</h2>
<button onclick="fetchGet()">Fetch Get</button>
<button onclick="fetchPost()">Fetch Post</button>
<script>
// 封装XMLHttpRequest发起ajax请求
let Axios = function({url, method, data}) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onreadystatechange = function() {
// readyState == 4说明请求已完成
if (xhr.readyState == 4 && xhr.status == 200) {
// 从服务器获得数据
resolve(xhr.responseText)
}
};
if(data){
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=utf-8');
xhr.send(Qs.stringify(data));
//xhr.send("a=1&b=2");
//xhr.send(JSON.stringify(data));
}else{
xhr.send();
}
})
}
// 需要post提交的数据
let postData = {
firstName: 'Fred',
lastName: 'Flintstone',
fullName: '姓 名',
arr:[1,2,3]
}
// 请求地址
let url = 'DemoServlet';
function xhrGet(){
Axios({
url: url+'?a=1',
method: 'GET'
}).then(function (response) {
console.log(response);
})
}
function xhrPost(){
Axios({
url: url,
method: 'POST',
data: postData
}).then(function (response) {
console.log(response);
})
}
function axiosGet(){
// 默认Content-Type = null
axios.get(url, {
params: {
ID: '12345'
}
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
}
function axiosPost(){
// 默认Content-Type = application/json;charset=UTF-8
axios.post(url, postData).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
// 默认Content-Type = application/x-www-form-urlencoded
axios({
method: 'post',
url: url,
data: Qs.stringify(postData)
}).then(function (response) {
console.log(response);
});
}
function fetchGet(){
fetch(url+'?id=1').then(res => res.text()).then(data => {
console.log(data)
})
}
function fetchPost(){
fetch(url, {
method: 'post',
body: postData
})
.then(res => res.text())
.then(function (data) {
console.log(data);
})
.catch(function (error) {
console.log('Request failed', error);
});
}
</script>
</body>
</html>
Релевантная информация:
- Стандарт XMLHttpRequest:xhr.spec.whatwg.org/
- Получить стандарт:fetch.spec.whatwg.org/
- Введение в XMLHttpRequest:developer.Mozilla.org/this-cn/docs/…
- получить введение:Developers.Google.com/Web/updates…
- Введение в выборку: новое поколение Ajax API:nuggets.capable/post/684490…
- исходный код аксиомы:github.com/axios/axios
задняя торцевая часть
Здесь мы используем платформу Java в качестве примера, чтобы показать, как серверная часть получает HTTP-запросы. В системе J2EE данные фактически принимаются и возвращаются черезServlet
завершить.
Сервлет получает и возвращает образец данных:
package com.demo.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DemoServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("-----------------start----------------");
System.out.println("Content-Type:" + request.getContentType());
// 打印请求参数
System.out.println("=========请求参数========");
Enumeration<String> em = request.getParameterNames();
while (em.hasMoreElements()) {
String name = (String) em.nextElement();
String value = request.getParameter(name);
System.out.println(name + " = " + value);
response.getWriter().append(name + " = " + value);
}
// 从inputStream中获取
System.out.println("===========inputStream===========");
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null)
sb.append(line);
} catch (Exception e) {
/* report an error */
}
System.out.println(sb.toString());
System.out.println("-----------------end----------------");
response.getWriter().append(sb.toString());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Релевантная информация:
- В чем суть сервлета и как он работает? :Ууху. Call.com/question/21…
- Как tomcat обрабатывает http-запросы? :blog.CSDN.net/QQ_38182963…
Сводка результатов
метод запроса | method | Тип содержимого запроса | Формат данных | Content-Type, полученный серверной частью | Можно получить данные через getParameter | Могу ли я получить данные через inputStream | Тип получения серверной части |
---|---|---|---|---|---|---|---|
XHR | Get | не установлен | параметр URL | null | могу | нет | пара ключ-значение |
XHR | Post | не установлен | json-строка | text/plain;charset=UTF-8 | нет | могу | нить |
XHR | Post | не установлен | строка формата a=1&b=2 | text/plain;charset=UTF-8 | нет | могу | нить |
XHR | Post | application/x-www-form-urlencoded | строка формата a=1&b=2 | application/x-www-form-urlencoded | могу | нет | Бэкенд получает пару ключ-значение с ключами a и b и значениями 1 и 2 |
XHR | Post | application/x-www-form-urlencoded | json-строка | application/x-www-form-urlencoded | могу | нет | Серверная часть получает пару ключ-значение, ключом которой являются данные json, а значение пусто. |
axios | Get | не установлен | параметр URL | null | могу | нет | пара ключ-значение |
axios | Post | не установлен | json-объект | application/json;charset=UTF-8 | нет | могу | json-строка |
axios | Post | не установлен | множество | application/json;charset=UTF-8 | нет | могу | строка массива |
axios | Post | не установлен | строка формата a=1&b=2 | application/x-www-form-urlencoded | могу | нет | пара ключ-значение |
fetch | Get | не установлен | параметр URL | null | могу | нет | пара ключ-значение |
fetch | Post | не установлен | строка формата a=1&b=2 | text/plain;charset=UTF-8 | нет | могу | а=1&b=2строка |
fetch | Post | не установлен | json-объект | text/plain;charset=UTF-8 | нет | могу | Бэкенд получает строку [object Object] |
fetch | Post | application/x-www-form-urlencoded;charset=UTF-8 | строка формата a=1&b=2 | application/x-www-form-urlencoded;charset=UTF-8 | могу | нет | пара ключ-значение |
Из содержимого приведенной выше таблицы видно, что любое использование get или content-typeapplication/x-www-form-urlencoded
При отправке данных серверный сервлет по умолчанию преобразует данные в пары ключ-значение. В противном случае строковые данные, отправленные внешним интерфейсом, должны быть получены из входного потока, а затем преобразованы в классы сущностей Java или объекты коллекции с использованием классов внутренних инструментов, таких как fastJSON.
Совместный инструмент отладки Postman
Вы можете загрузить плагин Postman в магазине приложений Chrome для имитации HTTP-запросов в браузере. Интерфейс Postman выглядит следующим образом:
проиллюстрировать:
- Отправьте запрос на получение напрямую с параметрами URL-адреса, а затем нажмите кнопку «Отправить».
- Для отправки почтового запроса есть три способа передачи данных;
form-data
,x-www-form-urlencoded
,raw
(необработанный)
Типы | Content-Type | иллюстрировать |
---|---|---|
form-data | Content-Type: multipart/form-data | Способ отправки вложения формы |
x-www-form-urlencoded | Content-Type: application/x-www-form-urlencoded | метод отправки формы формы |
raw | Content-Type: text/plain;charset=UTF-8 | Как отправить текст |