惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Latest news
Latest news
T
Troy Hunt's Blog
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
V
V2EX
博客园 - 司徒正美
B
Blog RSS Feed
AWS News Blog
AWS News Blog
MyScale Blog
MyScale Blog
Scott Helme
Scott Helme
Cisco Talos Blog
Cisco Talos Blog
Last Week in AI
Last Week in AI
NISL@THU
NISL@THU
博客园 - Franky
P
Proofpoint News Feed
博客园_首页
C
CERT Recently Published Vulnerability Notes
雷峰网
雷峰网
S
Schneier on Security
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
WordPress大学
WordPress大学
The Hacker News
The Hacker News
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
A
Arctic Wolf
Microsoft Azure Blog
Microsoft Azure Blog
T
The Exploit Database - CXSecurity.com
Engineering at Meta
Engineering at Meta
罗磊的独立博客
T
The Blog of Author Tim Ferriss
D
Darknet – Hacking Tools, Hacker News & Cyber Security
I
Intezer
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
SecWiki News
SecWiki News
云风的 BLOG
云风的 BLOG
美团技术团队
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
C
Cyber Attacks, Cyber Crime and Cyber Security
B
Blog
S
Security Affairs

披萨盒的赛博日志

谈谈工作了半年的感受 使用策略模式重构复杂业务分支 像 systemd 一样管理 MacOS 后台常驻任务 以ORM看封装的边界 Git Merge VS Git Rebase: 如何优雅地合并分支? 修改Linux内核模块以支持WG OpenLDAP折腾日记 非特权模式容器 ssh 登录问题 在 Linux 开发环境中使用网络代理 白嫖 Aseprite 像素绘图软件 MongoDB 增删改查 Python数据分析工具包-Numpy 解决 CLion 中文乱码问题 搭建 RLCraft 服务器 SpringBoot读取配置文件 Centos 配置 LNMP 环境 部署项目时遇到的坑 JavaScript 学习笔记 Eclipse配置Web开发环境 Vue2 基本知识 Ribbon 简单使用 Nacos 简单使用 Spring Cloud Alibaba 环境搭建 什么是RSS?什么是Feed?它们有什么关系? Docker基本使用 TensorFlow启用GPU加速 如何进行内网穿透 Hello World! Git基本使用 Butterfly常用标签外挂
浅谈 xhr 请求跨域问题
披萨盒 · 2022-09-07 · via 披萨盒的赛博日志

问题引出

我在 http://localhost:8080 放了一台后端服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.pushihao.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hello")
public class HelloController {

@RequestMapping("/h1")
public String h1() {
return "Hello, world!";
}

}

通过调用 http://localhost:8080/hello/h1 可以获得一个字符串

image-20220907131446988

我又在 http://localhost:5173 放了一台前端前端服务器,通过 xhr 请求调用后端的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup>
import axios from 'axios'
axios.defaults.timeout = 5000

axios.get("http://localhost:8080/hello/h1").then(
response => {
console.log(response)
}, error => {
console.log(error)
}
)
</script>

<template></template>
<style scoped></style>

结果这时,浏览器报错

image-20220907131920563

以上便是 xhr 请求跨域问题的一个经典例子


为什么会有请求跨域问题

什么导致的跨域请求问题?简单来说,浏览器的 同源策略 导致了跨域请求问题。

为什么要制定同源策略?官方是这样解释的:同源策略是一个重要的安全策略,它用于限制一个 origin 的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

什么样的 url 才算是同源呢?当两个 url 的**协议(protocol)域名(host)端口(port)**三者都相同时才算是同源。只要其中有一个不同,那么 url 就不算同源,进行的 http 请求就称为跨域请求。

跨域请求有什么限制?无法读取非同源网页的 cookie、localstorage 等、无法接触非同源网页的 DOM 和 js 对象、无法向非同源地址发送 Ajax 请求。


解决跨域请求问题

我们知道,同源策略是一个重要的安全策略,它可以减少我们被攻击的风险。但是对于正常的请求,我们希望可以接触跨域带来的一些限制。解决跨域请求问题的方法有很多,以下给出一些常用的解决方案。

后端使用 nginx 解决跨域问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 3500;
server_name localhost;
location / {


add_header Access-Control-Allow-Origin *;


add_header Access-Control-Allow-Credentials true;


add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';


add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';


if ($request_method = 'OPTIONS') {
return 204;
}


proxy_pass http://localhost:8080;
}
}

启动 Nginx 服务后,3500 端口被代理到 8080 端口,并且开启了允许所有域进行跨域请求

此时,修改前端请求的 url

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup>
import axios from 'axios'
axios.defaults.timeout = 5000

axios.get("http://localhost:3500/hello/h1").then(
response => {
console.log(response)
}, error => {
console.log(error)
}
)
</script>

<template></template>
<style scoped></style>

启动服务后,请求响应正常

image-20220907144118916


使用前端框架提供的代理服务器

注意:这种方法仅在调试阶段有效,部署到服务器上之后就没用了

使用原理:

只有前端在发送 Ajax 请求时会触发跨域请求,而两台后端服务器进行通信时是不会存在跨域的问题的,因此我们可以在前端与后端之间设置一台代理服务器,这台代理服务器与我们的前端项目保持同源,即:localhost:5173 ,我们的前端项目只负责请求这台代理服务器,由代理服务器向后端接口请求数据。

image-20220907145652664

  1. 对于 webpack + vue 的前端项目,可以使用 devServer 配置代理解决跨域问题

vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,









devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',

pathRewrite: {
'^/api': ''
},
ws: true,



changeOrigin: true
},


'/teacher': {
target: 'http://localhost:8082',
pathRewrite: {
'^/teacher': ''
},
ws: true,
changeOrigin: true
}
},
}
})

AxiosTest.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script setup>
import axios from 'axios'
axios.defaults.timeout = 5000

// 由于我们制定了重写规则,所以此处的 /api 会在发送请求时被略去
axios.get("/api/hello/h1").then(
response => {
console.log(response)
}, error => {
console.log(error)
}
)
</script>

<template></template>
<style scoped></style>

  1. 对于 vite + vue 的前端项目

vite.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'


export default defineConfig({
plugins: [vue()],
server: {
proxy: {
"/api": {
target: "http://localhost:8080",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
})

AxiosTest.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup>
import axios from 'axios'
axios.defaults.timeout = 5000

axios.get("/api/hello/h1").then(
response => {
console.log(response)
}, error => {
console.log(error)
}
)
</script>

<template></template>
<style scoped></style>

至此,问题解决!

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 披萨盒的赛博日志


avatar

披萨盒

反正身体这么好,今天继续笑下去吧

个人主页