10 междоменных решений (с окончательным трюком)

JavaScript

написать впереди

Эм. Это снова здесь, и это снова о кроссдоменности. Это старая тема. Раньше я думал, что нечего писать об этой базовой статье. Я бы подумал, что вы разбираетесь в нижнем слое. Но в последнее время разрабатывается"Плагин vscode"Обнаружено, что когда вы только начинаете что-то делать, вы не так много думаете, потому что вы не знакомы с этим, когда вы сталкиваетесь с чем-то, что вы не можете, вы просто хотите сначала найти решение, а затем углубиться через это решение. Например, междоменные, новички или новички с ним не так знакомы, поэтому имеет смысл перечислить некоторые решения, накопленные самостоятельно, а также некоторые часто используемые сценарии, чтобы принести одни идеи для решения проблем для других. (Я нашел его действительно ароматным после того, как закончил его писать. Я забыл, и я могу вернуться, чтобы увидеть его позже)

На самом деле текущая среда очень недружелюбна к начинающему фронтенду: с одной стороны, многие новички не пережили эпоху смены инструментов, а с другой стороны, итеративное обновление фреймворка происходит очень быстро. В прошлом вы, возможно, освоили несколько распространенных методов. но сейчасwebpack-dev-server,vue-cli,parcel, Эти леса инкапсулированы в слой, который может быть простым для тех, кто с ним знаком, но для тех, кто еще не начал, это просто черный ящик, хотя он очень удобен в использовании, но однажды столкнулся с проблема, у вас есть проблема с этим Если вы не знакомы, вы не будете знать, что не так. (Но не паникуйте, я расскажу о междоменном методе основного кли)

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

В этой статье будет использоваться""Что-как-почему""способ объяснить. А в How (Как решить междоменную проблему, будет предоставлено 11 решений для заголовка.)

"Важное примечание: в тексте веб-адрес - localhost: 8000, а адрес сервера - localhost: 8080. Надеюсь, вы помните этот момент, который будет использоваться на протяжении всего текста. Вы также можете подставить адреса с обоих концов здесь на свои адреса."

cors
cors

Все коды ниже находятся вGitHub.com/flower1995116/…

image-20200413192431636
image-20200413192431636

1. Что такое междоменный?

1. Та же политика происхождения

Междоменная проблема на самом деле вызвана политикой браузера в отношении одного и того же происхождения.

"Та же политика происхождения"является важной политикой безопасности, которая ограничиваетoriginКак документ или скрипты, которые он загружает, могут взаимодействовать с ресурсами из другого источника. Это может помочь заблокировать вредоносные документы и уменьшить возможные векторы атак.

--источник MDN

При перекрестном домене я получаю следующую ошибку

image-20200413205559124
image-20200413205559124

2. Гомологичный пример

Так что же значит быть гомологичным? Давайте сначала посмотрим на компоненты URL

http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument

image-20200412171942421
image-20200412171942421

только тогда, когда

"Протокол (протокол), домен (имя домена) и порт (порт) согласованы."

"Протокол (протокол), домен (имя домена) и порт (порт) согласованы."

"Протокол (протокол), домен (имя домена) и порт (порт) согласованы."

имеет такое же происхождение.

Следующие протоколы, имена доменов и порты одинаковы.

http://www.example.com:80/a.js

http://www.example.com:80/b.js

Как ни похожи следующие, это бесполезно, и они не гомологичны.

http://www.example.com:8080

http://www2.example.com:80

Обратите внимание, здесь порт написан, чтобы подчеркнуть разницу между портами. По умолчанию порт 80 можно не указывать для http и 443 для https. Не шутите, мы с вами говорили, что http://www.example.com:80 и http://www.example.com не имеют одинакового происхождения, это одно и то же.

http://www.example.com:80 === http://www.example.com

https://www.example.com:443 === https://www.example.com

Хорошо, позвольте мне объяснить.

Во-вторых, как решить междоменные?

1.CORS

Совместное использование ресурсов между источниками (CORS) представляет собой механизм, использующий дополнительныйHTTPзаголовок, чтобы сообщить браузерам, что веб-приложениям, работающим в одном источнике (домене), разрешен доступ к указанным ресурсам с разных исходных серверов. Когда ресурс загружается с того же сервера, что и сам ресурс"Различные домены, протоколы или порты"Когда запрос ресурса, инициирует ресурс"HTTP-запрос между источниками".

А в корсе будет简单请求а также复杂请求Концепция чего-либо.

"Поддержка браузера"

Пожалуйста, используйте JSONP при использовании браузеров IE

а. Простой запрос

не сработаетПредварительный запрос CORS. Такой запрос является «простым запросом», обратите внимание, что этот термин не относится кFetch(где определен CORS) спецификация. Запрос считается «простым запросом», если он соответствует всем следующим условиям:

Случай 1: используйте следующий метод (это означает, что запросы, отличные от следующих, являются непростыми запросами)

Случай 2: Искусственно установить заголовки запроса за пределами следующих наборов

Случай третий:Content-TypeЗначение ограничено одним из следующих трех: (например, application/json для непростых запросов)

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

Случай четвертый:

любой в запросеXMLHttpRequestUploadНи один из объектов не зарегистрировал ни одного прослушивателя событий;XMLHttpRequestUploadобъект может использоватьXMLHttpRequest.uploadдоступ к собственности.

Случай пятый:

не используется в запросеReadableStreamобъект.

б. Непростой запрос

кроме вышеуказанного.

в. Решения в узле

родной путь

Давайте взглянем на серверную часть решения.NodeсерединаCORSкод решения.

app.use(async (ctx, next) => {
  ctx.set("Access-Control-Allow-Origin", ctx.headers.origin);
  ctx.set("Access-Control-Allow-Credentials", true);
  ctx.set("Access-Control-Request-Method", "PUT,POST,GET,DELETE,OPTIONS");
  ctx.set(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept, cc"
  );
  if (ctx.method === "OPTIONS") {
    ctx.status = 204;
    return;
  }
  await next();
});
стороннее промежуточное ПО

Для удобства промежуточное ПО также можно использовать напрямую.

const cors = require("koa-cors");

app.use(cors());
Проблема с куки с cors

хочу пройтиcookieнужно выполнить 3 условия

1. настройки веб-запросаwithCredentials

Здесь по умолчанию в междоменных запросах браузер не несет куки. Но мы можем установитьwithCredentialsпередаватьcookie.

// 原生 xml 的设置方式
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
// axios 设置方式
axios.defaults.withCredentials = true;

2.Access-Control-Allow-Credentialsдляtrue

3.Access-Control-Allow-Originибо не*

Способ запроса здесь, вchromeВы можете увидеть возвращаемое значение в , но пока одно из вышеперечисленных условий не выполняется, браузер сообщит об ошибке, и возвращаемое значение не может быть получено.

image-20200412201424024
image-20200412201424024
Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/corslist' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
image-20200412201411481
image-20200412201411481
Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/corslist' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
image-20200412201530087
image-20200412201530087

г. Пример внешнего интерфейса

Продемонстрируйте фронтальную часть отдельно简单请求а также非简单请求

простой запрос
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
  axios.get("http://127.0.0.1:8080/api/corslist");
</script>
не простой запрос

Здесь мы добавляем не заданныйheadersголоваccДля достижения цели непростого запроса.

<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
  axios.get("http://127.0.0.1:8080/api/corslist", { headers: { cc: "xxx" } });
</script>
image-20200412201158778
image-20200412201158778
image-20200412195829232
image-20200412195829232
резюме

1. В новой версии хрома при отправке сложного запроса его не видноoptionsпросить. можно установить здесьchrome://flags/#out-of-blink-corsустановлен вdisbale, перезапустите браузер. Это видно по непростым запросамoptionsпросил.

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

2. Прокси узла переадресации

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

"Перед прокси"

image-20200412202320482
image-20200412202320482

"после прокси"

image-20200412202358759
image-20200412202358759

Таким образом, все ресурсы и запросы находятся под одним доменным именем.

Прокси в инструменте a.cli

1) Webpack (4.x)

существуетwebpackможно настроить вproxyДля быстрого получения возможности интерфейса прокси.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: {
    index: "./index.js"
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist")
  },
  devServer: {
    port: 8000,
    proxy: {
      "/api": {
        target: "http://localhost:8080"
      }
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "webpack.html"
    })
  ]
};

Измените метод запроса интерфейсного интерфейса, чтобы изменить его без имени домена. (потому что теперь это тот же запрос домена)

<button id="getlist">获取列表</button>
<button id="login">登录</button>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
  axios.defaults.withCredentials = true;
  getlist.onclick = () => {
    axios.get("/api/corslist").then(res => {
      console.log(res.data);
    });
  };
  login.onclick = () => {
    axios.post("/api/login");
  };
</script>
2) Vue-cli 2.x
// config/index.js

...
proxyTable: {
  '/api': {
     target: 'http://localhost:8080',
  }
},
...
3) Vue-cli 3.x
// vue.config.js 如果没有就新建
module.exports = {
  devServer: {
    port: 8000,
    proxy: {
      "/api": {
        target: "http://localhost:8080"
      }
    }
  }
};
4) Parcel (2.x)
// .proxyrc
{
  "/api": {
    "target": "http://localhost:8080"
  }
}

Увидев это, я ляпну в сердце фразу ххх. Напишу файл конфигурации на время, proxyTable на время, а прокси на время. Зачем столько форм? Я не могу учиться, я не могу учиться. . . Но не паникуйте, есть способ. Все вышеперечисленные конфигурации имеют общий базовый пакет.http-proxy-middleware.Внутри необходимо использовать все видыwebsocket,rewriteДля других функций вы можете напрямую посмотреть конфигурацию этой библиотеки. Принцип работы библиотеки http-proxy-middleware смотрите в моей статьеGitHub.com/flower1995116/…Конечно. . . Запись местоположения для конфигурации по-прежнему неоднородна. Позвольте мне научить вас навыку поиска.Вам не нужно помнить, где написана вышеуказанная конфигурация.Вы можете напрямую поискать в гугле ххх прокси для того фреймворка, который вы хотите.

Например, прокси-сервер vue-cli 2, прокси-сервер webpack и т. д. В основном вы найдете ответ по настройке на официальном сайте, который универсален и удобен.

б. Используйте свой собственный прокси-инструмент

cors-anywhere

"Сервер"

// Listen on a specific host via the HOST environment variable
var host = process.env.HOST || "0.0.0.0";
// Listen on a specific port via the PORT environment variable
var port = process.env.PORT || 7777;

var cors_proxy = require("cors-anywhere");
cors_proxy
  .createServer({
    originWhitelist: [], // Allow all origins
    requireHeader: ["origin", "x-requested-with"],
    removeHeaders: ["cookie", "cookie2"]
  })
  .listen(port, host, function() {
    console.log("Running CORS Anywhere on " + host + ":" + port);
  });

"интерфейсный код"

<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
  axios.defaults.withCredentials = true;
  getlist.onclick = () => {
    axios
      .get("http://127.0.0.1:7777/http://127.0.0.1:8080/api/corslist")
      .then(res => {
        console.log(res.data);
      });
  };
  login.onclick = () => {
    axios.post("http://127.0.0.1:7777/http://127.0.0.1:8080/api/login");
  };
</script>

"Показать результаты"

image-20200413161243734
image-20200413161243734

"недостаток"

Файл cookie не может быть доставлен, причина в том, что это прокси-библиотека, и автор считает, что передавать файл cookie посередине слишком небезопасно. https://github.com/Rob--W/cors-anywhere/issues/208#issuecomment-575254153

c.charles

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

Это артефакт тестирования и разработки.Введение и использование

Использование charles для кроссдоменности по сути является перехватом и прокси запросов.

существуетtools/map remoteустановить прокси в

image-20200412232733437
image-20200412232733437
image-20200412232724518
image-20200412232724518
интерфейсный код
<button id="getlist">获取列表</button>
<button id="login">登录</button>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
  axios.defaults.withCredentials = true;
  getlist.onclick = () => {
    axios.get("/api/corslist").then(res => {
      console.log(res.data);
    });
  };
  login.onclick = () => {
    axios.post("/api/login");
  };
</script>
внутренний код
router.get("/api/corslist", async ctx => {
  ctx.body = {
    data: [{ name: "秋风的笔记" }]
  };
});

router.post("/api/login", async ctx => {
  ctx.cookies.set("token", token, {
    expires: new Date(+new Date() + 1000 * 60 * 60 * 24 * 7)
  });
  ctx.body = {
    msg: "成功",
    code: 0
  };
});
Эффект

Посетите http://localhost:8000/charles

image-20200412232231554
image-20200412232231554
image-20200412232752837
image-20200412232752837

Идеальное решение.

Хорошо. Вот еще одно замечание. существуетMac mojave 10.14В серединеcharlesНе удается поймать локальный пакет. В это время вам нужно настроить доменное имя, а затем настроитьhostsназначен на127.0.0.1. Затем измените метод доступаhttp://localhost.charlesproxy.com:8000/charles.

image-20200412233258107
image-20200412233258107
image-20200412233317027
image-20200412233317027

3. Обратный прокси Nginx

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

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

image-20200412233536522
image-20200412233536522

Настроить хосты

127.0.0.1 local.test

настроить nginx

server {
        listen 80;
        server_name local.test;
        location /api {
            proxy_pass http://localhost:8080;
        }
        location / {
            proxy_pass http://localhost:8000;
        }
}

запустить nginx

sudo nginx

перезапустить nginx

sudo nginx -s reload

выполнить

интерфейсный код

<script>
  axios.defaults.withCredentials = true;
  getlist.onclick = () => {
    axios.get("/api/corslist").then(res => {
      console.log(res.data);
    });
  };
  login.onclick = () => {
    axios.post("/api/login");
  };
</script>

внутренний код

router.get("/api/corslist", async ctx => {
  ctx.body = {
    data: [{ name: "秋风的笔记" }]
  };
});

router.post("/api/login", async ctx => {
  ctx.cookies.set("token", token, {
    expires: new Date(+new Date() + 1000 * 60 * 60 * 24 * 7)
  });
  ctx.body = {
    msg: "成功",
    code: 0
  };
});
Эффект

доступhttp://local.test/charles

отображение в браузере

image-20200413000229326
image-20200413000229326

4.JSONP

JSONPв основном используютscriptМетки не имеют этой функции междоменных ограничений.

"ограничения на использование"

Поддерживается только метод GET. Если вы хотите использовать полный интерфейс REST, используйте CORS или другие методы прокси.

"Анализ процесса"

1. Внешний интерфейс определяет функцию разбора (например, jsonpCallback=function(){....})

2. Оберните параметры запроса в виде params и объявите функцию выполнения (например, cb=jsonpCallback)

3. Серверная часть получает функцию выполнения (jsonpCallback), объявленную интерфейсом, и передает ее интерфейсу, принимая параметры и вызывая функцию выполнения.

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

бэкэнд реализация

const Koa = require("koa");
const fs = require("fs");
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.path === "/api/jsonp") {
    const { cb, msg } = ctx.query;
    ctx.body = `${cb}(${JSON.stringify({ msg })})`;
    return;
  }
});

app.listen(8080);

Обычный пример js

<script type="text/javascript">
  window.jsonpCallback = function(res) {
    console.log(res);
  };
</script>
<script
  src="http://localhost:8080/api/jsonp?msg=hello&cb=jsonpCallback"
  type="text/javascript"
></script>

Пример JQuery Ajax

<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
<script>
  $.ajax({
    url: "http://localhost:8080/api/jsonp",
    dataType: "jsonp",
    type: "get",
    data: {
      msg: "hello"
    },
    jsonp: "cb",
    success: function(data) {
      console.log(data);
    }
  });
</script>

"Принципиальный анализ"

На самом деле это магия js

Сначала рассмотрим простейший вызов js. Что ж, естественный звонок.

<script>
  window.jsonpCallback = function(res) {
    console.log(res);
  };
</script>
<script>
  jsonpCallback({ a: 1 });
</script>

Немного переделаем, в виде внешних ссылок.

<script>
  window.jsonpCallback = function(res) {
    console.log(res);
  };
</script>
<script src="http://localhost:8080/api/a.js"></script>

// http://localhost:8080/api/a.js jsonpCallback({a:1});

Давайте еще раз переделаем, js этой внешней ссылки мы рассматриваем как динамический интерфейс, потому что сам ресурс такой же, как и интерфейс, это запрос, он тоже содержит различные параметры, и его тоже можно динамически возвращать.

<script>
  window.jsonpCallback = function(res) {
    console.log(res);
  };
</script>
<script src="http://localhost:8080/api/a.js?a=123&cb=sonpCallback"></script>

// http://localhost:8080/api/a.js jsonpCallback({a:123});

Вы внимательно, внимательно, есть ли у jsonp преимущество загрузки скрипта js, метод загрузки - это просто другой способ сказать. Это также говорит нам правду, многие вещи не такие волшебные, они находятся в пределах знаний, которые вы узнали. Например, персиковые деревья и ивы, если вы думаете о них как о вещах с большим размахом для запоминания и понимания, тогда в мире так много деревьев, вы действительно измотаны, вы относитесь к ним как к деревьям, о хо? Вы вдруг обнаружите, что немного знаете обо всех деревьях в мире, у них у всех есть листья, фотосинтез.... пример конечно есть, но надо только запомнить нюансы и взяться за ствол. . . Что ж, это правда в любом случае.

5.Websocket

WebSocketСпецификация определяет API, который устанавливает «сокетное» соединение между веб-браузером и сервером. Проще говоря: между клиентом и сервером существует постоянное соединение, и обе стороны могут начать отправку данных в любой момент. Подробные руководства см. на странице https://www.html5rocks.com/zh/tutorials/websockets/basics/.

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

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

<script>
  let socket = new WebSocket("ws://localhost:8080");
  socket.onopen = function() {
    socket.send("秋风的笔记");
  };
  socket.onmessage = function(e) {
    console.log(e.data);
  };
</script>

задняя торцевая часть

const WebSocket = require("ws");
const server = new WebSocket.Server({ port: 8080 });
server.on("connection", function(socket) {
  socket.on("message", function(data) {
    socket.send(data);
  });
});

6.window.postMessage

"window.postMessage()"способ безопасного осуществления связи между источниками. Как правило, сценарии для двух разных страниц могут выполняться только в том случае, если страницы, на которых они выполняются, имеют одинаковый протокол (обычно https), номер порта (443 по умолчанию для https) и хост (модуль двух страниц).Document.domainустановлено на одно и то же значение), два скрипта могут взаимодействовать друг с другом."window.postMessage()"методы обеспечивают управляемый механизм для обхода этого ограничения и безопасны при правильном использовании.

использовать

1. Перенос данных страницы и открытие нового окна

2. Передача сообщений между несколькими окнами

3. Страницы и вложенные сообщения iframe

Применение

Подробное использование см. на странице https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage.

otherWindow.postMessage(message, targetOrigin, [transfer]);

  • otherWindow: ссылка на другие окна, такие как свойство contentWindow iframe, выполнитьwindow.openвозвращаемый объект окна, именованный или пронумерованный в числовом видеwindow.frames.

  • message: данные для отправки в другие окна.

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

  • передача (необязательно): это строка, передаваемая одновременно с сообщением.TransferableОбъекты. Право собственности на эти объекты будет передано получателю сообщения, а отправитель больше не сохранит право собственности

Пример

index.html

<iframe
  src="http://localhost:8080"
  frameborder="0"
  id="iframe"
  onload="load()"
></iframe>
<script>
  function load() {
    iframe.contentWindow.postMessage("秋风的笔记", "http://localhost:8080");
    window.onmessage = e => {
      console.log(e.data);
    };
  }
</script>

another.html

<div>hello</div>
<script>
  window.onmessage = e => {
    console.log(e.data); // 秋风的笔记
    e.source.postMessage(e.data, e.origin);
  };
</script>

7.document.domain + Iframe

С 7-го по 9-й способ, думаю, чужое написание уже очень хорошее, для полноты картины возьму чужое. Если есть какое-то сходство... (нет, это одно и то же...) Не говорите этого.

"Этот метод можно использовать только в том случае, если доменные имена второго уровня совпадают, напримерa.test.comа такжеb.test.comПрименяется к этому методу". Просто добавьте на страницуdocument.domain ='test.com'Указывает, что доменные имена второго уровня одинаковы для обеспечения междоменного доступа.

www.   baidu.  com     .
三级域  二级域   顶级域   根域
// a.test.com
<body>
  helloa
  <iframe
    src="http://b.test.com/b.html"
    frameborder="0"
    onload="load()"
    id="frame"
  ></iframe>
  <script>
    document.domain = "test.com";
    function load() {
      console.log(frame.contentWindow.a);
    }
  </script>
</body>
// b.test.com
<body>
  hellob
  <script>
    document.domain = "test.com";
    var a = 100;
  </script>
</body>

8.window.location.hash + Iframe

Принцип реализации

Принцип заключается в передаче URL-адреса с хешем и передаче данных через промежуточную страницу без междоменного доступа.

Процесс реализации

Сначала a.html передает хеш-значение в c.html, затем c.html получает хэш-значение, затем передает хэш-значение в b.html, и, наконец, b.html помещает результат в хэш-значение a. HTML. Точно так же a.html и b.html находятся в одном домене, обаhttp://localhost:8000, а c.htmlhttp://localhost:8080

// a.html
<iframe src="http://localhost:8080/hash/c.html#name1"></iframe>
<script>
  console.log(location.hash);
  window.onhashchange = function() {
    console.log(location.hash);
  };
</script>
// b.html
<script>
  window.parent.parent.location.hash = location.hash;
</script>
// c.html
<body></body>
<script>
  console.log(location.hash);
  const iframe = document.createElement("iframe");
  iframe.src = "http://localhost:8000/hash/b.html#name2";
  document.body.appendChild(iframe);
</script>

9.window.name + Iframe

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

где a.html и b.html находятся в одном домене, обаhttp://localhost:8000, а c.htmlhttp://localhost:8080

// a.html
<iframe
  src="http://localhost:8080/name/c.html"
  frameborder="0"
  onload="load()"
  id="iframe"
></iframe>
<script>
  let first = true;
  // onload事件会触发2次,第1次加载跨域页,并留存数据于window.name
  function load() {
    if (first) {
      // 第1次onload(跨域页)成功后,切换到同域代理页面
      iframe.src = "http://localhost:8000/name/b.html";
      first = false;
    } else {
      // 第2次onload(同域b.html页)成功后,读取同域window.name中数据
      console.log(iframe.contentWindow.name);
    }
  }
</script>

b.html — это промежуточная прокси-страница с тем же доменом, что и a.html, и ее содержимое пусто.

// b.html
<div></div>
// c.html
<script>
  window.name = "秋风的笔记";
</script>

Атрибут src iframe переносится из чужого домена в локальный домен, а междоменные данные передаются из чужого домена в локальный домен через window.name iframe. Это ловко обходит ограничения междоменного доступа браузера, но в то же время это безопасная операция.

10. Включить междоменный доступ в браузере (идеальное решение)

На самом деле междоменная проблема - это политика браузера, источник - он, так можно ли отключить эту функцию?

Ответ положительный.

"Примечание. Поскольку браузер является входом на многие веб-страницы. Можем ли мы также использовать отдельный выделенный хост-браузер для открытия и отладки нашей страницы разработки, такой как клиент. Например, здесь используется chrome canary. Это браузер, который я использую для отладки страниц. Он не будет использоваться для доступа к другим веб-адресам. Так что это также относительно безопасно. Конечно, этот метод рекомендуется только тогда, когда вы действительно сломлены междоменными пытками. После использования включите его обычным способом, чтобы случайно не использовать этот режим для других целей."

Windows

找到你安装的目录
.\Google\Chrome\Application\chrome.exe --disable-web-security --user-data-dir=xxxx

Mac

~/Downloads/chrome-dataЭтот каталог можно настроить.

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary  --disable-web-security --user-data-dir=~/Downloads/chrome-data

Показать результаты

image-20200413143102377
image-20200413143102377

Что ж, его приятно использовать, но еще раз, пожалуйста, не применяйте этот метод легкомысленно. Этот метод подобен Кулаку Семи Ран. Он очень силен при правильном использовании, но легко навредить себе, если не использовать его. это хорошо.

3. Зачем вам кроссдоменность?

С самого начала мы знали, что междоменный доступ существует только на стороне браузера. Браузер обеспечивает доступ к сети. Мы открываем много страниц в нашем браузере. Это такая открытая форма, поэтому нам нужно его ограничить. Например, когда лес большой, там есть все виды птиц, нам нужна единая спецификация, чтобы договориться об обеспечении этой безопасности.

1. Ограничьте запросы из разных источников

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

2. Ограничить операции с домом

Приведу пример, вы сначала заходите на сайт www.baidu.com, а потом заходите на мой сайт.

https://zerolty.com/node-demo/index.html

image-20200413190413758
image-20200413190413758

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

можно добавить в заголовок возврата httpX-Frame-Options: SAMEORIGINЗапретить добавление других в iframe.

напиши в конце

Наиболее часто используемые методы выше - это первые 4 метода, особенно второй метод очень распространен.Я также упомянул множество примеров, вы можете переварить их медленно. Я надеюсь, что в будущем появится более безопасный способ ограничить доступ в Интернет и решить головную боль междоменного доступа, хахахаха.

"Есть незрелая идея, такой браузер можно использовать только для разрешения доступа в интранет/локальную сеть, и он специально используется разработчиками для отладки страниц.Для статических ресурсов можно настроить белый список, чтобы не было кросса -проблема с доменом. , 23333. Если в приведенном выше есть какая-либо ошибка, пожалуйста, укажите на нее как можно скорее, и я исправлю ее, чтобы не вводить вас в заблуждение."

Добро пожаловать в публичный аккаунт"«Записки осеннего ветра».", в основном записывайте инструменты, которые интересны в повседневной жизни, и делитесь практиками разработки, сохраняя глубину и направленность.

weixin-gongzhonghao

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

1581349909092

Ссылаться на

https://stackoverflow.com/questions/12296910/so-jsonp-or-cors

https://juejin.cn/post/6844903767226351623#heading-18

https://juejin.cn/post/6844903553069219853

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

В этой статье используетсяmdniceнабор текста