HTTP-протокол и совместная отладка внешнего и внутреннего интерфейса

задняя часть внешний интерфейс HTTPS HTTP

представлять

   В сценарии разработки, когда интерфейс и сервер разделены, неизбежна совместная отладка интерфейса и сервера. На этапе совместной отладки часто встречаются различные проблемы, такие как искажение символов, данные (строки, массивы, Json-объекты), передаваемые с фронтенда, не могут быть нормально разобраны на бэкенде и т.д.
В этой статье мы надеемся начать с первоисточника, прояснить первопричину проблемы, быстро определить местонахождение проблемы, сделать удобной регулировку переднего и заднего шарнира и упростить сброс горшка. .

HTTP-протокол

   Причина, по которой здесь будет представлен протокол HTTP, заключается в том, что совместная отладка интерфейса и сервера неотделима от HTTP. Понимание протокола HTTP поможет вам лучше понять процесс передачи данных, а также лучше проанализировать, в чем заключается проблема, что удобно для устранения неполадок.

1. Введение

   Прежде всего, http — это протокол без сохранения состояния, то есть каждое взаимодействие клиента и сервера не имеет состояния, обычно с использованием файлов cookie для сохранения состояния.
   На следующем рисунке показана общая структура http-запросов и ответов (все изображения в этой части взяты из "HTTP Authoritative Guide"):

проиллюстрировать:
   Как видно из рисунка выше, HTTP-запрос условно делится на три части: стартовая строка, заголовок и тело. В строке запуска запроса указывается способ запроса, адрес запроса и версия http-протокола. Кроме того, первая часть — это то, что мы часто называем заголовком http.

2. HTTP method

  Следующие часто используемые методы HTTP-запросов и их введение:

проиллюстрировать:

  1. Обычно мы используем get in post.
  2. Включать ли тело означает, имеет ли содержимое запроса тело. Например, в методе 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]видимый.

Релевантная информация:

  1. Таблица сравнения типов контента:tool.oschina.net/commons
  2. Типы содержимого формы:Я 3.org/TR/HTML4/in…
  3. Исследование проблемы декодирования знака плюс в пробел при декодировании символов:много Study.com/2017/12/06/…
  4. Понимание типа содержимого HTTP:дорога домой.?/2015/07/19/…

4. Набор символов и кодировка

Причина, по которой вам необходимо понимать эту часть совместной отладки внешнего и внутреннего интерфейса, заключается в том, что при взаимодействии данных между внешним и внутренним интерфейсом вы часто сталкиваетесь с проблемой искаженных символов. содержание, вы можете легко решить проблему искаженных символов.

Одна картинка стоит тысячи слов:

   На рисунке значение charset равноiso-8859-6, в котором подробно описывается полный процесс текста от кодирования до декодирования для отображения.

Релевантная информация:

  1. Список наборов символов:Woohoo.IANA.org/assignments…
  2. Детали кодировки символов:много 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>

Релевантная информация:

  1. Стандарт XMLHttpRequest:xhr.spec.whatwg.org/
  2. Получить стандарт:fetch.spec.whatwg.org/
  3. Введение в XMLHttpRequest:developer.Mozilla.org/this-cn/docs/…
  4. получить введение:Developers.Google.com/Web/updates…
  5. Введение в выборку: новое поколение Ajax API:nuggets.capable/post/684490…
  6. исходный код аксиомы: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);
	}
}

Релевантная информация:

  1. В чем суть сервлета и как он работает? :Ууху. Call.com/question/21…
  2. Как 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 выглядит следующим образом:

проиллюстрировать:

  1. Отправьте запрос на получение напрямую с параметрами URL-адреса, а затем нажмите кнопку «Отправить».
  2. Для отправки почтового запроса есть три способа передачи данных;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 Как отправить текст