如何解决前端跨域问题 ----- 通过CORS、NGINX、JSONP解决

产生跨域的原因

由于浏览器的安全策略,避免在跨域名访问的时候页面资源被篡改。
当请求源地址目的地址协议域名端口有一个不同就会产生跨域。
本文主要提供三个方式来解决跨域问题,分别是服务端配置Access-Control-Allow-Origin、反向代理、JSONP

如何解决跨域

后端处理 CORS跨域

在后端响应头增加 Access-Control-Allow-Origin配置

//允许来自 www.google.com 源访问
Access-Control-Allow-Origin:www.google.com
//允许所有源访问
Access-Control-Allow-Origin:*

如果资源是html页面,可以设置header的meta标签

<meta http-equiv="Access-Control-Allow-Origin" content="*">

node.js 服务端配置

const http = require("http")
const port = 8001
const hosthame = "localhost"
const server = http.createServer(function (request, response) {
  response.setHeader("Content-Type", "text/plain")
  response.statusCode = 200
  response.end("Hello World!")
})
server.listen(port, () => {
  // 终端打印如下信息
  console.log(`Server running at http://${hosthame}:${port}/`)
})

启动后服务端对应的地址为http://localhost:8001/启动node服务
前端发axios请求给到服务端

<script setup>
import axios from 'axios'
axios.defaults.baseURL = 'http://localhost:8001/';
axios.post().then((res) => {
  console.log(res)
})
</script>

启动前端工程对应地址为http://localhost:3000/
启动前端工程
两个地址的端口号不同请求时发生跨域,发生cors错误
请求跨域报错
此时修改node.js 服务端配置,服务端配置 Access-Control-Allow-Origin允许所有源的访问

const http = require("http")
const port = 8001
const hosthame = "localhost"
const server = http.createServer(function (request, response) {
  response.setHeader("Content-Type", "text/plain")
  response.setHeader("Access-Control-Allow-Origin", "*") // 服务端配置 Access-Control-Allow-Origin
  response.statusCode = 200
  response.end("Hello World!")
})
server.listen(port, () => {
  // 终端打印如下信息
  console.log(`Server running at http://${hosthame}:${port}/`)
})

重启服务,重新发起请求,成功获取响应
请求成功

前端配置代理服务

可以有两种方式来配置反向代理
1.通过配置反向代理NGINX来实现代理转发

devServer: {
   //设置基本目录结构
    contentBase: [path.resolve(__dirname, '../')],
    //服务器的IP地址,可以使用IP也可以使用localhost
    host: '0.0.0.0',
    //服务端压缩是否开启
    compress: true,
    //配置服务端口号
    port: '1337',
	proxy: {
		'/api': {
			target: 'xxxxxxxx', // 目的地址
			changeOrigin: true,
			pathRewrite: {
				'/api': ''//代理的路径
			}
		}
    }
}

2.直接修改nginx配置文件
severProxy:配置目的地址
location:待反向代理的文件路径
NGINX反向代理配置

JSONP

可以实现跨域读取数据,基于浏览器支持以<img><link><script>标签的srchref加载资源,这种方式也需要服务端同步改造,服务端接受请求后返回一个回调函数callback,调用前端定义好的函数,从而实现跨域请求。

  • JSONP 仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求
  • JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象

node.js服务端配置

const http = require("http") // 通过require将http库包含到程序中
const url = require("url") // 引入url模块解析url字符串
const server = http.createServer() // 创建新的HTTP服务器
server.on("request", function (req, res) {
  // 通过request事件来响应request请求
  let urlPath = url.parse(req.url).pathname // 获取url的路径信息
  let searchParams = new URLSearchParams(req.url.split("?")[1]) // 获取url的参数信息 用于提取callback变量
  if (urlPath === "/jsonp" && searchParams.has("callback")) {
    // 对应的路径为jsonp 并且参数包含callback变量时
    res.writeHead(200, { "Content-Type": "application/json;charset=utf-8" })
    let data = {
      // 模拟返回数据
      name: "Jeremy",
      age: "28",
    }
    data = JSON.stringify(data)
    let callback = searchParams.get("callback") + "(" + data + ")" //获取变量callback对应的数值 searchParams.get("callback")
    res.end(callback)
  } else {
    res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" })
    res.end("Hello World")
  }
})
server.listen("8001", () => {
  console.log(`Server running at http://${hosthame}:${port}/`)
})

前端配置

<html>
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JSONP</title>
  </head>
  <script>
    function resFun(res) {
      console.log(res)
    }
  </script>
  <body>
    <div id="app"></div>
    <script src="http://localhost:8001/jsonp?callback=resFun"></script>
  </body>
</html>

结果
jsonp跨域

将前后端服务放在同一服务器下

跨域问题主在前后端分离流行起来之后比较常见,也可以将前后端服务放在同一服务器内来规避。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端解决Access-Control-Allow-Origin错误的问题中,有几种常见的解决方案。一种是通过配置nginx来处理跨域请求。通过在被请求的接口配置nginx的location代理,并添加header,实现跨域访问。例如,在nginx配置中添加以下代码: ``` location /promotion/activityPro { proxy_pass http://frontHost/promotion/activityPro; add_header 'Access-Control-Allow-Origin' '*'; # 可选项,可以添加其他的header # add_header 'Access-Control-Allow-Methods' 'GET, POST'; # add_header 'Access-Control-Allow-Credentials' "true"; # add_header 'Access-Control-Max-Age' 86400; # add_header 'Access-Control-Allow-Header' 'Content-Type,*'; } ``` 另一个解决方案是使用JSONPJSONP是一种跨域请求的方法,通过在前端发起请求时,将回调函数作为参数传递给服务端,服务端返回的数据会被包裹在回调函数中返回给前端,从而实现跨域请求。 还有一种解决方案是使用CORS(跨域资源共享)。CORS是W3C的标准,通过在服务端返回的响应头中添加"Access-Control-Allow-Origin"字段,指定允许访问的域名。例如,可以使用以下代码指定允许访问的域名为"http://172.20.0.206": ``` 'Access-Control-Allow-Origin: http://172.20.0.206' ``` 此外,还可以通过设置"Access-Control-Allow-Credentials"字段来允许携带认证信息(cookies)。 总结起来,前端解决Access-Control-Allow-Origin错误的方法有:配置nginx代理实现跨域访问、使用JSONP进行跨域请求、使用CORS在服务端返回的响应头中添加"Access-Control-Allow-Origin"字段来指定允许访问的域名。具体选择哪种方法取决于你的需求和服务端的配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Access-Control-Allow-Origin跨域解决及详细介绍](https://blog.csdn.net/MicroAnswer/article/details/102913571)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [跨域(Access-Control-Allow-Origin)解决方案详解](https://blog.csdn.net/jiabeis/article/details/103459765)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值