Изучите внешний интерфейс (8), инкапсулируйте ajax, http, междоменные проблемы.

внешний интерфейс JavaScript

предисловие

  • Когда мы умело используем axios, fetch и promises, будем ли мы помнить, ajax года, давайте рассмотрим принцип ajax и почувствуем классику

http-протокол

Протокол HTTP, а именно протокол передачи гипертекста (Hypertext transfer protocol). Это правило, которое определяет связь между браузером и сервером.

Протокол HTTP указываетпроситьа такжеоткликстандарт

запрос и сообщение запроса

Подробное объяснение сообщения запроса запроса на получение

//--------------------------请求行--------------------------------
// GET  请求方式
// 01.php?username=pp&password=123456    请求路径+参数(注意点)
// HTTP/1.1 HTTP的版本号
GET /day02/01.php?username=pp&password=123456 HTTP/1.1

//--------------------------请求头--------------------------------
Host: www.study.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

//----------------------------请求体-------------------------------------
//get请求没有请求体,但是参数会拼接到请求行中

Сообщение запроса для запроса POST

//-----------------------请求行---------------------------------------------
POST /01.php HTTP/1.1

//-----------------------请求头--------------------------------------------
Host: www.study.com
Connection: keep-alive
//传递的参数的长度。
Content-Length: 29
Cache-Control: max-age=0
Origin: http://www.study.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
//内容类型:表单数据,如果是post请求,必须指定这个属性。
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Referer: http://www.study.com/01-login.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

//------------------------请求体------------------------------------------
username=why&password=123456

GET-запрос против POST-запроса

  • GET-запрос не имеет тела запроса, потому что параметры GET-запроса вклеены в адресную строку
  • Запрос POST имеет тело запроса, которое является переданным параметром.
  • Запросы POST должны указывать атрибут content-type.

Ответ и ответное сообщение

//---------------------状态行(响应行)-------------------------------
//HTTP/1.1  HTTP版本
//200 响应的状态
	//200表示成功
	//304表示读缓存
	//404表示找不到资源
	//500表示服务端错误
HTTP/1.1 200 OK

//----------------------响应头-----------------------------------------------
Date: Thu, 22 May 2019 16:51:22 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Content-Length: 18
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
//内容类型,告诉浏览器该如何解析响应结果
Content-Type: text/html;charset=utf-8
//-----------------------响应体------------------------------------------------
hello world

AJAX

Асинхронный [e'sɪŋkrənəs] Javascript И XML, AJAX — это не новый язык, а комплексное использование существующих технологий. Суть в том, чтобы общаться с сервером асинхронно на основе протокола HTTP.

Синхронный и асинхронный

Синхронные и асинхронные концепции:

Синхронизация: Относится к выполнению действий одно за другим. Не выполняйте следующую задачу, пока не будет выполнена предыдущая

Асинхронный: не зависит от текущей задачи, две вещи выполняются одновременно, и когда выполняется одна вещь, другая не затрагивается.

В программировании: асинхронное выполнение программного кода не будет блокировать выполнение другого программного кода, тем самым повышая общую эффективность выполнения.

Асинхронное приложение веб-страницы:

  1. Убедитесь, что ваше имя пользователя уже существует (получите информацию при вводе и сравните ее с фоном).
  2. Советы по поиску Baidu и отображение соответствующего контента (во время ввода и поиска того, что вам может понадобиться).
  3. Комментарии Sina Weibo (загружаются асинхронно).

XMLHttpRequest может запрашивать обработчики данных асинхронно, обеспечивая частичное обновление веб-страниц вместо обновления всей страницы.

Объект XMLHttpRequest

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

请求由客户端发起,其规范格式为:请求行、请求头、请求主体。

отправить запрос на получение

XMLHttpRequest отправляет HTTP-запросы асинхронно, поэтому при отправке запросов также необходимо следовать протоколу HTTP.

Шаги для отправки запроса на получение с помощью XMLHttpRequest

//1. 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest();

//2. 设置请求行
// 第一个参数:请求方式  get/post
// 第二个参数:请求的地址 需要在url后面拼上参数列表
xhr.open("get", "01.php?name=why");

//3. 设置请求头
//请求头中可以设置Content-Type,用以说明请求主体的内容是如何编码,get请求时没有请求体,无需设置

//4. 设置请求体
//get请求的请求体为空,因为参数列表拼接到url后面了
xhr.send(null);

будь осторожен :

  • получить запрос, при настройке строки запроса вам нужно соединить список параметров с задней частью URL-адреса
  • В запросе на получение не нужно устанавливать заголовок запроса и не нужно объяснять метод кодирования тела запроса.
  • Тело запроса на получение равно null

отправить почтовый запрос

var xhr = new XMLHttpRequest();

// 1. 设置请求行 post请求的参数列表在请求体
xhr.open("post", "02.php");

// 2. 设置请求头, post 请求必须要设置 content-type, 标记请求体内容的解析方式, 不然后端无法解析获取数据
xhr.setRequestHeader( "content-type", "application/x-www-form-urlencoded" );

// 3. 设置请求体
xhr.send( "name=Jepson&age=18" );

будь осторожен :

  • пост-запрос, при настройке строки запроса не объединять список параметров
  • сообщение должно установить тип содержимого в заголовке запроса как application/x-www-form-urlencoded, отметив метод разбора тела запроса.
  • Почтовый запрос должен установить список параметров в тело запроса.

Получить ответ в состоянии готовности

readyState: записывает текущее состояние объекта XMLHttpRequest.

readyState有五种可能的值:
xhr.readyState = 0时,UNSENT open尚未调用
xhr.readyState = 1时,OPENED open已调用
xhr.readyState = 2时,HEADERS_RECEIVED 接收到头信息
xhr.readyState = 3时,LOADING 接收到响应主体
xhr.readyState = 4时,DONE 响应完成

不用记忆状态,只需要了解有状态变化这个概念

Ответ HTTP разделен на три части: строку состояния, заголовок ответа и тело ответа.

//给xhr注册一个onreadystatechange事件,当xhr的状态发生状态发生改变时,会触发这个事件。
xhr.onreadystatechange = function () {
  
  if(xhr.readyState == 4){
    
    //1. 获取状态行
    console.log("状态行:"+xhr.status);
    
    //2. 获取响应头
    console.log("所有的响应头:"+xhr.getAllResponseHeaders());
    console.log("指定响应头:"+xhr.getResponseHeader("content-type"));
    
    //3. 获取响应体
    console.log(xhr.responseText);
    
  }
  
}

Взаимодействие данных

浏览器端只是负责用户的交互和数据的收集以及展示,真正的数据都是存储在服务器端的。

我们现在通过ajax的确可以返回一些简单的数据(一个字符串), 
但是在实际开发过程中,肯定会会设计到大量的复杂类型的数据传输,
比如数组、对象等,但是每个编程语言的语法都不一样。

因此我们会采用通过的数据交换格式(XML、JSON)来进行数据的交互。

XML (его можно понять, сейчас это редкость)

что такое XML

  • XML означает расширяемый язык разметки.
  • XML — это язык разметки, очень похожий на HTML.
  • XML предназначен для передачи данных, а не для их отображения
  • Теги XML не являются предопределенными. Вам нужно определить свои собственные метки.

Спецификация грамматики

  • В первой строке должна быть информация о версии
  • Должен быть один корневой элемент (есть ровно один)
  • Метки не могут иметь пробелов, цифр или . в начале, с учетом регистра
  • Никакой перекрестной вложенности, все двойные теги, если это один тег, он должен быть закрыт
  • Двойные кавычки атрибута (браузер автоматически исправляет его в двойные кавычки)
  • Специальные символы для использования объектов
  • Комментарии аналогичны HTML
<?xml version="1.0" encoding="utf-8" ?>
<students>
    <student>
        <name>张三</name>
        <age>18</age>
        <gender>男</gender>
        <desc>路人甲</desc>
    </student>
    <student>
        <name>李四</name>
        <age>20</age>
        <gender>男</gender>
        <desc>路人乙</desc>
    </student>
</students>

php получить содержимое файла xml

// 注意: 如果需要返回 xml 数据, 需要将 content-type 改成 text/xml, 不然浏览器以 text/html 解析
header( 'content-type:text/xml;charset=utf-8' );
// file_get_content 用于获取文件的内容
// 参数: 文件的路径
$result = file_get_content( "data.xml" );
echo $result;

js парсинг xml

//获取服务端返回的xml数据,需要使用xhr.responseXML,这是一个document对象,可以使用DOM中的方法查找元素。
var data = xhr.responseXML;
//获取所有的学生
var students = data.querySelectorAll("student");

Недостатки: Хотя сложные данные могут быть описаны и переданы, их анализ слишком сложен, а объем велик, поэтому редко используется для разработки реализации.

JSON-данные

JSON (JavaScript Object Notation, JS Object Notation) — это упрощенный формат обмена данными. Он основан на спецификации ECMAScript и использует независимый от языка программирования текстовый формат для хранения и представления данных.

  • Данные в парах ключа-значений в
  • Данные разделяются запятыми (последняя пара ключ-значение не может содержать запятых)
  • Фигурные скобки содержат объекты, квадратные скобки содержат массивы
  • Используйте двойные кавычки для ключей
var obj = {a: 'Hello', b: 'World'}; //这是一个对象

// 这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}';

Когда данные JSON передаются на разных языках, тип — строка, и разные языки имеют соответствующие методы синтаксического анализа, после завершения синтаксического анализа его можно легко использовать.

php обрабатывает json

  • Ассоциативный массив php ==> json ( json_encode )
// php的关联数组
$obj = array(
  "a" => "hello",
  "b" => "world",
  "name" => "why"
);
//json字符串
$json = json_encode( $obj );
echo $json;
  • json ==> объекты php/ассоциативный массив (из json_decode)
$json = '{"a": "Hello", "b": "World"}';//json字符串
//第一个参数:json字符串
//第二个参数:
//false,将json转换成对象(默认)
//true:将json转换成数组(推荐)
$obj = json_decode($json,true);
echo $obj['a'];

//通过json文件获取到的内容就是一个json字符串。
$data = file_get_contents("data.json");

//将json转换成数组
$result = json_decode($data, true);
print_r($result);

JS обрабатывает json

  • Объект JS ==> Строка JSON JSON.stringify(obj)
    //obj是一个js对象
    var obj = {a: 'Hello', b: 'World'}
    //result就变成了一个json字符串了
    var result = JSON.stringify(obj);// '{"a": "Hello", "b": "World"}'
  • Строка JSON ==> объект JS JSON.parse(obj)
    //json是一个json字符串
    var json = '{"a": "Hello", "b": "World"}';
    //obj就变成了一个js对象
    var obj = JSON.parse(json);// {a: 'Hello', b: 'World'}

Совместимость

Теперь он вообще совместим до IE8.Я увижу его здесь позже и знаю, что он имеет дело с совместимостью.

var xhr = null;
if(XMLHttpRequest){
  //现代浏览器 IE7+
  xhr = new  XMLHttpRequest();
}else{
  //老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}

Инкапсулирует служебные функции ajax

Каждый раз, когда отправляется запрос ajax, шаги одинаковы, и много кода повторяется, и мы можем полностью инкапсулировать его в функцию инструмента.

//1. 创建xhr对象
//2. 设置请求行
//3. 设置请求头
//3. 设置请求体
//4. 监听响应状态
//5. 获取响应内容

извлечение параметров

имя параметра Тип параметра описывать передать по значению По умолчанию
type string метод запроса get/post Пока вы не проходите пост, он получает
url string адрес запроса адрес интерфейса Если адрес не передан, запрос не отправляется
async boolean Это асинхронно? true/fase Пока false не передается, это правда, асинхронный запрос
data object запросить данные {key:value,key1:value2} Этот объект нужно вставить в формат параметра uname=hucc&upass=12345
dataType string Возвращаемый тип данных xml/json/text text
success function Вызывается при успешном ответе - -
error function Вызывается, когда ответ не работает - -

Обнаружение параметра

// 要求参数obj必须传递,否则直接不发送请求
if(!obj || typeof obj !== "object"){
  return;
}
// 如果type传递的是post,那就发送post请求,否则发送get请求
var type = obj.type == "post"?"post":'get';
var url = obj.url;
if(!url){
  return;
}
// 只有当async传递了false,才会发送同步请求,不然只发送异步请求
var async = obj.async == false? false:true;

полная версия

var $ = {
  ajax: function (options) {
    //如果options参数没有传递,直接返回。
    if (!options || typeof options !== "object") {
      return;
    }
    
    //处理默认参数
    //如果参数不是post,那就默认为get
    var type = options.type == "post" ? "post" : "get";
    //如果没有传url,那就传当前地址
    var url = options.url || location.pathname;
    //如果参数不是false,那就默认是true,发异步请求
    var async = options.async == false ? false : true;
    
    var params = this.getParams(options.data);
    
    var xhr = new XMLHttpRequest();
    
    //设置请求行
    if (type == "get") {
      url = url + "?" + params;
    }
    xhr.open(type, url, async);
    
    //设置请求头
    if (type == "post") {
      xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    }
    //设置请求参数
    xhr.send(params);
    
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          /*根据响应头的content-type属性指定方法接收到的内容*/
          var contentType = xhr.getResponseHeader('content-type');
          var data = null;
          if (contentType.indexOf('json') > -1) {
            data = JSON.parse(xhr.responseText);
          } else if (contentType.indexOf('xml') > -1) {
            data = xhr.responseXML;
          } else {
            data = xhr.responseText;
          }
          /*执行成功函数*/
          options.success && options.success(data);
        } else {
          options.error && options.error(xhr.responseText);
        }
        
      }
    }
  },
  getParams: function (obj) {
    //将obj对象转换成参数
    //将对象转换成参数列表
    if (!obj) {
      return null;
    }
    var arr = [];
    for (var k in obj) {
      arr.push(k + "=" + obj[k]);
    }
    return arr.join("&");
  }
  
}

метод ajax в jQuery

jQuery предоставляет нам более мощную инкапсуляцию Ajax.

$.ajax

список параметров

имя параметра описывать стоимость Пример
url адрес интерфейса url:"02.php"
type метод запроса get/post type:"get"
timeout сверхурочное время в миллисекундах timeout:5000
dataType Формат, возвращаемый сервером json/xml/текст (по умолчанию) dataType:"json"
data Данные запроса отправлены объект data:{name:"zs", age:18}
beforeSend Функция обратного вызова перед звонком function(){} beforeSend:function(){ alert(1) }
success функция обратного вызова успеха function (data) {} success:function (data) {}
error Неудачная функция обратного вызова function (error) {} error:function(data) {}
complete Функция обратного вызова после завершения function () {} complete:function () {}

Пример использования:

$.ajax({
  type:"get",//请求类型
  url:"02.php",//请求地址
  data:{name:"zs", age:18},//请求数据
  dataType:"json",//希望接受的数据类型
  timeout:5000,//设置超时时间
  beforeSend:function () {
    //alert("发送前调用");
  },
  success:function (data) {
    //alert("成功时调用");
    console.log(data);
  },
  error:function (error) {
    //alert("失败时调用");
    console.log(error);
  },
  complete:function () {
    //alert("请求完成时调用");
  }
});

другие API

//$.post(url, callback, [dataType]);只发送post请求
//$.get(url, callback, [dataType]);
//$.getJSON(url, callback);
//$.getScript(url,callback);//载入服务器端的js文件
//$("div").load(url);//载入一个服务器端的html页面。

Гомологичные и кроссдоменные

гомология

Основные концепции политики одинакового происхождения

В 1995 году компания Netscape ввела в браузеры политику одинакового происхождения. В настоящее время все браузеры реализуют эту политику. Политика одинакового происхождения: изначально это означает, что файл cookie, установленный веб-страницей A и веб-страницей B, не может быть открыт, если только эти две веб-страницы не имеют «одного и того же происхождения». Так называемый «гомологичный» относится к «трем идентичным».

协议相同
域名相同
端口相同

Например, этот URLhttp://www.example.com/dir/page.htmlсоглашениеhttp://,

доменное имяwww.example.com, порт80(Порт по умолчанию можно не указывать). Его гомологии таковы.

http://www.example.com/dir2/other.html:同源

file:///F:/phpStudy/WWW//04.html 不同源(协议不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)

Цель политики одинакового происхождения

Цель политики единого источника — обеспечить безопасность пользовательской информации и предотвратить кражу данных вредоносными веб-сайтами.

Ограничения политики одного и того же происхождения

С развитием Интернета «политика одного и того же происхождения» становится все более и более строгой. В настоящее время, если это не одно и то же происхождение, будут ограничены следующие три поведения.

1. Cookie、LocalStorage 和 IndexDB 无法读取。
2. DOM 无法获得。
3. AJAX 请求不能发送。

Хотя эти ограничения необходимы, они также негативно сказываются на нашем повседневном развитии. Например, в реальном процессе разработки серверная часть часто настраивается на одном или даже кластерном сервере, а клиентская страница размещается на другом отдельном сервере. Тогда в это время будут разные источники.Если мы знаем, что оба сайта безопасны, мы надеемся, что два сайта из разных источников смогут запрашивать данные друг у друга. Это требует использованияперекрестный домен.

перекрестный домен

jsonp (нет проблем с совместимостью)

JSONP (JSON с дополнением) можно использовать для решения проблемы междоменного доступа к данным в основных браузерах.

Принцип: сервер возвращает вызов определенной функции js и передает данные сервера в виде параметров функции.Этот метод требует взаимодействия между интерфейсом и сервером.

scriptНа теги не распространяется политика одинакового происхождения, они могут быть загружены в файлы JavaScript где угодно. Похожие такжеimgа такжеlinkЭтикетка

<!--不受同源策略限制的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>

процесс эволюции jsonp 1

php-файл

header("content-type:text/html;charset=utf-8");
echo "alert(1111)";

HTML-файл

<script src="http://www.api.com/testjs.php"></script>

Принцип: на самом деле не имеет значения, какой файл является путем к src.Независимо от того, вводится ли файл js или файл php, окончательный возврат в браузер представляет собой строку, поэтому наш тег script может импортировать файл php.

Процесс эволюции jsonp 2

php-файл

header("content-type:text/html;charset=utf-8");
echo "var a = 118;";

HTML-файл

<script src="http://www.api.com/testjs.php"></script>
<script>
  //a打印出来了118
  console.log(a);
</script>

Мы сейчас сделали одно, получили данные из php файлов из разных источников

Недостатки: Тег скрипта для получения данных должен быть написан перед используемым тегом скрипта, и необходимо убедиться, что данные могут быть отображены до того, как данные будут визуализированы.

эволюция jsonp 3

php-код

header("content-type:text/html;charset=utf-8");
$arr = array(
    "name"=>"zs",
    "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo "func($result)";

js-код

<script>
  function func(data) {
    console.log(data);
  }
</script>
<script src="http://www.api.com/testjs.php"></script>

Недостаток: серверная часть должна знать имя метода, объявленного внешним интерфейсом, прежде чем серверная часть сможет его вызвать.

процесс эволюции jsonp 4

php-код

header("content-type:text/html;charset=utf-8");
$arr = array(
    "name"=>"zs",
    "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo $_GET['callback']."($result)";

код javascript

function fun(data) {
  console.log(data);
}
var button = document.querySelector("button");
button.onclick = function () {
  var script = document.createElement("script");
  script.src = "http://www.api.com/testjs.php?callback=fun";
  document.body.appendChild(script);
}
  1. Проще говоря, принцип jsonp заключается в использовании тега скрипта src для запроса ресурсов без ограничений политики одного и того же происхождения.
  2. Возвращает вызов функции на стороне сервера, который будет содержать фактические параметры вызываемой в данный момент функции.
  3. На стороне браузера программе нужно объявить глобальную функцию, и соответствующее значение, возвращаемое сервером, можно получить через формальные параметры

Каждый должен знать принцип jsonp, но не стоит слишком беспокоиться об этом принципе, потому что jquery уже запаковал его за нас, и нам очень удобно его использовать.

jQuery инкапсулирует jsonp

//使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
$.ajax({
  type:"get",
  url:"http://www.why.com/testjs.php",
  dataType:"jsonp",
  data:{
    uname:"why",
    upass:"123456"
  },
  success:function (info) {
    console.log(info);
  }
});

XMLHttpRequest2.0

XMLHttpRequest — это встроенный объект JavaScript, который позволяет Javascript выполнять асинхронную HTTP-связь. В феврале 2008 г. был предложен проект XMLHttpRequest Level 2.

Недостатки старых версий XMLHttpRequest:

1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
2. 传输数据时,没有进度信息,只能提示完成与否。
3. 受到了"同源策略"的限制

Особенности новой версии:

1. 可以设置timeout超时时间
2. 可以使用formData对象管理表单数据
3. 允许请求不同域名下的数据(跨域)
4. 支持上传二进制文件
5. 可以获取数据传输的进度信息

Примечание: объекты, которые мы создаем с помощью нового XMLHttpRequest, теперь являются объектами версии 2.0. Мы уже изучили синтаксис версии 1.0, а теперь можем изучить некоторые новые возможности версии 2.0.

тайм-аут установить тайм-аут

xhr.timeout = 3000;//设置超时时间
xhr.ontimeout = function(){
  alert("请求超时");
}

formData управляет данными формы

Объект formData похож на метод сериализации jquery для управления данными формы.

使用特点: 
1. 实例化一个formData对象, new formData(form); form就是表单元素
2. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
3. formData有一个append方法,可以添加参数。formData.append("id", "1111");
4. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。

Пример кода:

//1. 使用formData必须发送post请求
    xhr.open("post", "02-formData.php");
    
//2. 获取表单元素
var form = document.querySelector("#myForm");
//3. 创建form对象,可以直接作为send的参数。
var formData = new FormData(form);

//4. formData可以使用append方法添加参数
formData.append("id", "1111");

//5. 发送,不需要指定请求头,浏览器会自动选择合适的请求头
xhr.send(formData);

Файл загружен

В прошлом для загрузки файлов требовалась загрузка формы, но загрузка формы была синхронной, то есть при загрузке файлов страницу необходимо было отправить и обновить, что делало работу пользователя недружелюбной.Объект formData в xhr2.0 поддерживает асинхронный файл загрузки.

var formData = new FormData();
//获取上传的文件,传递到后端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);

Отображение информации о ходе выполнения файла

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

1. 需要注册 xhr.upload.onprogress = function(e){} 事件,用于监听文件上传的进度.注意:需要在send之前注册。
2. 上传的进度信息会存储事件对象e中
3. e.loaded表示已上传的大小   e.total表示整个文件的大小

Ссылка на код:

xhr.upload.onprogress = function (e) {
  
  inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
  span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}

xhr.send(formData);

Если загруженный файл превышает 8M, php сообщит об ошибке, и его необходимо настроить, чтобы разрешить php загружать большие файлы.

Совместное использование ресурсов между источниками (CORS) (совместимо с IE10+)

использование кор

新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。 это называется«Совместное использование ресурсов из разных источников»(Совместное использование ресурсов из разных источников, сокращенно CORS).

Предварительные условия для совместного использования ресурсов между источниками (CORS)

  • Браузеры поддерживают эту функцию (совместимость с IE10+)
  • Сервер должен разрешать такой междоменный доступ.

Сервер допускает междоменный код:

//允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");
//允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");

Конкретный процесс CORS (понять)

  1. Браузер отправляет перекрестный запрос

  2. После того, как сервер получает междоменный запрос, он добавляет конфигурацию разрешения ресурса Access-Control-Allow-Origin Header в заголовок ответа. отправить ответ

  3. После того, как браузер получит ответ, проверьте, установлен ли онheader('Access-Control-Allow-Origin:请求源域名或者*');

    Если текущий домен уже авторизован, вернуть результат вJavaScript. В противном случае браузер игнорирует ответ.

В заключение:

  1. Междоменное поведение — это поведение браузера. Отзывчивость вернулась, но механизм безопасности браузера ограничен, а содержимое междоменного ответа игнорируется.
  2. Междоменная проблема между сервером и сервером отсутствует

Сравнение jsonp и cors

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

Другие междоменные средства

Следующие методы в принципе не нужны, просто поймите:

1. Одно и то же доменное имя верхнего уровня может быть решено с помощью domain.name, то есть установка domain.name = доменное имя верхнего уровня (например, example.com) одновременно 2. документ.домен + iframe 3. имя_окна + iframe 4. location.hash + iframe 5. окно.postMessage()