моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Оглавление
1. Политика браузера в отношении одного и того же происхождения
1.1 Обзор политики одного и того же происхождения
2. Каковы ограничения на междоменные транзакции?
2.2 Ограничить доступ к файлам cookie
2.3 Ограничить Ajax для получения данных
3 момента, на которые стоит обратить внимание
4CORS решает междоменные проблемы Ajax
4.2CORS решает простые междоменные запросы
4.4CORS решает сложные междоменные запросы
4.5. Используйте библиотеку cors для быстрого завершения настройки.
5JSONP решает междоменные проблемы
6Настройте прокси для решения междоменных проблем
6.1 Настройте прокси-сервер самостоятельно
6.2 Используйте Nginx для создания прокси-сервера
6.3 Сборка сервера с помощью scaffolding
Адрес кода git clone https://gitee.com/childe-jia/cross-domain-test.git
Политика одного и того же происхождения — это политика, которой следуют браузеры для обеспечения безопасности ресурсов. Эта политика накладывает некоторые ограничения на доступ к ресурсам.
Описание политики одного и того же происхождения от W3C:Политика одинакового происхождения。
1 исходные компоненты
2В таблице ниже только два источника в последней строке имеют одинаковое происхождение.
Источник 1 | Источник 2 | Это гомологично? |
http://www.xyz.com/home | https://www.xyz.com/home | ⛔Неоднородный️ |
http://www.xyz.com/home | http://mail.xyz.com/home | ⛔Неоднородный |
http://www.xyz.com:8080/home | http://www.xyz.com:8090/home | ⛔Неоднородный |
http://www.xyz.com:8080/home | http://www.xyz.com:8080/search | ✅То же происхождение︎ |
3 запроса происхождения
4 Неоригинальный запрос
5 Краткое описание: Если «источник» не соответствует «целевому источнику», это означает «неисточник», также известный как «гетероисточник» или «междоменный».
Например, если есть два источника: «Источник А» и «Источник Б», которые имеют «разное происхождение», то в браузере будут действовать следующие ограничения:
Сценарий «Источника А» не может получить доступ к DOM «Источника Б».
- <!-- <iframe id="framePage" src="./demo.html"></iframe> -->
- <iframe id="framePage" src="https://www.baidu.com"></iframe>
-
- <script type="text/javascript" >
- function showDOM(){
- const framePage = document.getElementById('framePage')
- console.log(framePage.contentWindow.document) //同源的可以获取,非同源的无法获取
- }
- </script>
«Источник А» не может получить доступ к файлу cookie «Источника Б».
- <iframe id="baidu" src="http://www.baidu.com" width="500" height="300"></iframe>
-
- <script type="text/javascript" >
- // 访问的是当前源的cookie,并不是baidu的cookie
- console.log(document.cookie)
- </script>
«Источник А» может отправлять запросы «Источнику Б», но не может получать данные ответа от «Источника Б».
- const url = 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'
- let result = await fetch(url)
- let data = await result.json();
- console.log(data)
Примечание. Среди вышеперечисленных ограничений наибольшее влияние оказывает ограничение браузера на сбор данных Ajax, которое часто встречается в реальной разработке.
Полное название CORS: Совместное использование ресурсов между источниками (Cross-Origin Resource Sharing) — это набор спецификаций, используемых для управления проверкой браузером междоменных запросов. Сервер следует спецификации CORS и добавляет специальные заголовки ответов для управления проверкой браузера. Общие правила заключаются в следующем:
●Сервер явно отклоняет междоменные запросы или не указывает это, и браузер не проходит проверку.
●Сервер четко указывает, что междоменные запросы разрешены, и проверка браузера проходит.
Примечание. Использование CORS для решения междоменных проблем является наиболее ортодоксальным способом и требует, чтобы сервер был «собственным».
Общая идея: когда сервер отвечает, он ясно выражает, что определенному источнику разрешено инициировать междоменные запросы, добавляя заголовок ответа Access-Control-Allow-Origin, а затем браузер передает его непосредственно во время проверки.
Основной код на стороне сервера (в качестве примера возьмем экспресс-фреймворк):
- // 处理跨域中间件
- function corsMiddleWare(req,res,next){
- // 允许 http://127.0.0.1:5500 这个源发起跨域请求
- // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
-
- // 允许所有源发起跨域请求
- res.setHeader('Access-Control-Allow-Origin','*')
- next()
- }
-
- // 配置路由并使用中间件
- app.get('/',corsMiddleWare,(req,res)=>{
- res.send('hello!')
- })
CORS делит запросы на две категории: ① простые запросы и ② сложные запросы.
простой запрос | Сложный запрос |
✅Метод запроса (метод): GET, HEAD, POST. | 1 — это либо простой запрос, либо сложный запрос. |
✅Поля заголовка запроса должны соответствовать«Спецификация безопасности CORS» | |
✅Значение Content-Type заголовка запроса может быть только следующими тремя: |
Что касается предполетных запросов:
Заголовок запроса | значение |
Источник | Источник запроса |
Метод запроса контроля доступа | Фактически запрошенный метод HTTP |
Заголовки-запросов-контроля-доступа | Пользовательские заголовки, используемые в фактическом запросе (если есть) |
1 Шаг первый. Сервер сначала передает предварительный запрос браузера. Серверу необходимо вернуть следующий заголовок ответа:
заголовок ответа | значение |
Доступ-Контроль-Разрешить-Происхождение | разрешенные источники |
Методы-разрешения-контроля-доступа | разрешенные методы |
Заголовки Access-Control-Allow | Разрешены пользовательские заголовки |
Доступ-Контроль-Макс-Возраст | Время кэширования результатов предполетных запросов (необязательно) |
2 Шаг 2. Обработка фактического междоменного запроса (так же, как вы обрабатываете простые междоменные запросы).
Основной код сервера:
- // 处理预检请求
- app.options('/students', (req, res) => {
- // 设置允许的跨域请求源
- res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
- // 设置允许的请求方法
- res.setHeader('Access-Control-Allow-Methods', 'GET')
- // 设置允许的请求头
- res.setHeader('Access-Control-Allow-Headers', 'school')
- // 设置预检请求的缓存时间(可选)
- res.setHeader('Access-Control-Max-Age', 7200)
- // 发送响应
- res.send()
- })
-
- // 处理实际请求
- app.get('/students', (req, res) => {
- // 设置允许的跨域请求源
- res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
- // 随便设置一个自定义响应头
- res.setHeader('abc',123)
- // 设置允许暴露给客户端的响应头
- res.setHeader('Access-Control-Expose-Headers', 'abc')
- // 打印请求日志
- console.log('有人请求/students了')
- // 发送响应数据
- res.send(students)
- })
В приведенной выше конфигурации вам необходимо настроить заголовок ответа самостоятельно или вручную инкапсулировать промежуточное программное обеспечение. С помощью библиотеки cors вы можете выполнить настройку более удобно.
●Установить корс
npm i cors
●Простая конфигурация
app.use(cors())
●Полная настройка cors
- // cors中间件配置
- const corsOptions = {
- origin: 'http://127.0.0.1:5500', // 允许的源
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允许的方法
- allowedHeaders: ['school'], // 允许的自定义头
- exposedHeaders: ['abc'], // 要暴露的响应头
- optionsSuccessStatus: 200 // 预检请求成功的状态码
- };
-
- app.use(cors(corsOptions)); // 使用cors中间件
По умолчанию js не может получить доступ к заголовку ответа, установленному серверной частью, и должен быть предоставлен серверной частью.
1Обзор JSONP: JSONP использует<script>标签可以跨域加载脚本,且不受严格限制的特性,可以说是程序员智慧的结晶,早期一些浏览器不支持 CORS 的时,可以靠 JSONP 解决跨域。
2Основной процесс:
3Иллюстрация:
4 примера кода:
- <button onclick="getTeachers()">获取数据</button>
-
- <script type="text/javascript" >
- function callback(data){
- console.log(data)
- }
-
- function getTeachers(url){
- // 创建script元素
- const script = document.createElement('script')
- // 指定script的src属性
- script.src= 'http://127.0.0.1:8081/teachers'
- // 将script元素添加到body中触发脚本加载
- document.body.appendChild(script)
- // script标签加载完毕后移除该标签
- script.onload = ()=>{
- script.remove()
- }
- }
- </script>
5jQuery, инкапсулированный jsonp
?callback=?' имеет фиксированный формат и будет автоматически анализироваться.
- $.getJSON('http://127.0.0.1:8081/teachers?callback=?',(data)=>{
- console.log(data)
- })
Между серверами нет междоменных проблем. Вам необходимо использовать экспресс для запуска статических ресурсов, чтобы гарантировать, что ваш сервер и страница находятся в одном и том же источнике.
- // 启动静态资源 让服务器跟页面同一个源
- app.use(express.static("./public"));
Настройте прокси с помощью http-proxy-middleware
- const { createProxyMiddleware } = require('http-proxy-middleware');
-
- app.use('/api',createProxyMiddleware({
- target:'https://www.toutiao.com',
- changeOrigin:true,
- pathRewrite:{
- '^/api':''
- }
преимущество:
недостаток:
сцены, которые будут использоваться:
Общая идея: пусть nginx играет две роли: как сервера статического контента и как прокси-сервера.
Измените конфигурацию nginx следующим образом. Обратите внимание, что корневой каталог nginx предпочтительно не является диском C.
- # 配置nginx根目录
- location / {
- root D:dist;
- index index.html index.htm;
- }
-
- # 配置代理
- location /dev/ {
- # 设置代理目标
- proxy_pass http://sph-h5-api.atguigu.cn/;
- }
2. Измените внешний проект так, чтобы все запросы перенаправлялись в /dev, а затем переупаковывались.
- const request = axios.create({
- baseURL:'/dev',
- timeout:10000
- })
Затем напрямую получите доступ к серверу nginx. Например, если nginx работает на порту 8099, получите доступ.
http://localhost:8099
Тогда вы столкнетесь с проблемой обновления 404, добавьте конфигурацию nginx, чтобы решить ее.
-
- # 配置nginx根目录
- location / {
- root D:dist;
- index index.html index.htm;
- try_files $uri $uri/ /index.html; # 解决刷新404
- }
- # 配置代理
- location /dev/ {
- # 设置代理目标
- proxy_pass http://sph-h5-api.atguigu.cn/;
- }
Добавление этих двух "/" исключает dev.
1. Используйте файл vue.config.js для настройки прокси:
Создайте файл vue.config.js в корневом каталоге проекта Vue и добавьте следующий код:
- module.exports = {
- devServer: {
- proxy: {
- '/api': {
- target: 'http://api.example.com',
- changeOrigin: true,
- pathRewrite: {
- '^/api': ''
- }
- }
- }
- }
- }
В приведенном выше коде мы используемdevServer
Элементы конфигурации для настройки прокси-сервера.вproxy
Свойства используются для настройки правил прокси,/api
Указывает путь к интерфейсу, требующему проксирования.target
Атрибут представляет адрес целевого сервера прокси-сервера.changeOrigin
Атрибут указывает, следует ли изменить адрес источника запроса.pathRewrite
Свойство, используемое для переопределения запрошенного пути.
преимущество:
недостаток:
сцены, которые будут использоваться: