解决跨域请求的四种方法
跨域跨域就是请求的url中的“协议”、“域名”、“端口号”其中任何一种不一样都是属于跨域。解决跨域的主要的四种方法是jsonp、跨域资源共享CORS(Cross-Origin Resource Sharing)、proxy代理、webpack中间件。jsonp解决跨域jsonp只能解决get方法。在这里设置两个不同的域名,即http://localhost:3000与http://localhos
·
跨域
- 跨域就是请求的url中的“协议”、“域名”、“端口号”其中任何一种不一样都是属于跨域。解决跨域的主要的四种方法是jsonp、跨域资源共享CORS(Cross-Origin Resource Sharing)、proxy代理、webpack中间件。
jsonp解决跨域
- jsonp只能解决get方法。
- 在这里设置两个不同的域名,即http://localhost:3000与http://localhost:3001,端口号不同即为跨域。
为jsonp启动两个不同服务,前端端口号为3000,利用node.js实现,设置代码如下:
const express = require("express");
const app = express();
const path = require("path");
const port = 3000;
app.use(express.static(path.join(__dirname, "public")));
app.get("/", (req, res) => res.send("Hello World!"));
app.listen(port, () => console.log(`3000端口号,启动成功!!`));
后端设置的端口号为3001,代码如下
const express = require('express')
const app = express()
const port = 3001
app.get('/test', (req,res)=>{
// 接收客户端传递光来的函数名称
const params = req.query.callback;
// 将函数名称对应的函数调用返回给客户端
const fn = params+"({name:'zs'})";
res.send(fn)
})
app.listen(port, () => console.log(`3001端口号,启动成功!!`))
分别启动之后,在前端中设置如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">发送请求</button>
<script>
function fn(data) {
console.log('客户端的fn被调用了!')
console.log(data)
}
const btn1 = document.querySelector('#btn1');
btn1.onclick = function () {
jsonp({
url: 'http://localhost:3001/test?callback=fn'
})
}
function jsonp(options) {
// 动态创建script标签
const script = document.createElement('script');
// 设置非同源地址
script.src = options.url
document.body.appendChild(script)
// 为script标签添加onload事件,否则每发送一次请求就会在body里添加一个script,最终会导致body中有很多的script标签
script.onload = function () {
document.body.removeChild(script)
}
}
</script>
</body>
</html>
运行结果
可以将前端代码封装一下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">发送请求</button>
<button id="btn2">发送请求</button>
<script>
const btn1 = document.querySelector('#btn1');
const btn2 = document.querySelector('#btn2');
btn1.onclick = function () {
jsonp({
url: 'http://localhost:3001/test',
// 设置参数
data: {
name: 'lisi',
age: 20
},
success: function (data) {
console.log(123)
console.log(data)
}
})
}
btn2.onclick = function () {
// jsonp({
// url: 'http://localhost:3001/test?callback=fn'
// })
jsonp({
url: 'http://localhost:3001/test',
// 设置参数
data: {
name: 'lisi',
age: 20
},
success: function (data) {
console.log(456)
console.log(data)
}
})
}
function jsonp(options) {
// 动态创建script标签
const script = document.createElement('script');
var params = ""
for (let attr in options.data) {
params += '&' + attr + "=" + options.data[attr];
}
// 设置函数名,让每次调用这个函数的时候window都能挂载不同的函数名,解决后端处理的数据是异步的问题,这样就不会覆盖第一次调用了。
const fileName = 'myJson' + Math.random().toString().replace('.', '');
// 将传递过来的函数变成全局函数
// window.fn = options.success;
window[fileName] = options.success
// 设置非同源地址
script.src = options.url + '?callback=' + fileName + params;
document.body.appendChild(script)
// 为script标签添加onload事件,否则每发送一次请求就会在body里添加一个script,最终会导致body中有很多的script标签
script.onload = function () {
document.body.removeChild(script)
}
}
</script>
</body>
</html>
运行结果
CORS解决跨域
- 在这里,将webpack-dev-server将前端启动的端口号设置为8080,后端的端口号利用node.js设置成3000。
首先下载webpack、webpack-cli、webpack-dev-server、html-webpack-plugin。
package.js文件如下:
{
"scripts": {
"dev": "webpack-dev-server"
},
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2"
}
}
webpack.config.js文件配置如下:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 入口
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/' // 资源路径
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html',
template: 'index.html'
})
]
}
- 前端必须要有一个index.html和src文件夹下的index.js
设置index.js内容:
console.log('log')
const xhr = new XMLHttpRequest()
// 设置发送的请求地址时是同源的
xhr.open('get', 'http://localhost:3000/user', true);
xhr.onload = function () {
console.log(xhr.responseText)
}
xhr.send()
后端代码设置
const express = require('express')
const app = express()
const port = 3000
// CORS:后端解决跨域问题
var allowCrossDomian = function(req,res,next){
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Contro-Allowl-Headers", "*")
res.header("Access-Control-Allow-Methods", "*")
// 必须要要有这个,否则不会执行下面的代码
next()
}
app.use(allowCrossDomian)
app.get('/user', function(req,res){
res.json({name : 'jack'})
console.log(123)
})
app.listen(port, () => console.log(`服务端已启动,端口号3000!`))
proxy代理解决跨域
- 其他不变,只需要在webpack.config.js中添加如下代码即可。
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 入口
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/' // 资源路径
},
// 添加的代码
devServer: {
proxy: { // 代理 前端解决跨域问题
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api': '' //这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http://40.00.100.100:3002/user/add',直接写‘/api/user/add’即可
}
}
}
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html',
template: 'index.html'
})
]
}
修改index.js中的请求路径为:
console.log('log')
const xhr = new XMLHttpRequest()
// 设置发送的请求地址时非同源的
// xhr.open('get', 'http://localhost:3000/user', true);
// 设置proxy代理的请求路径
xhr.open('get', '/api/user', true);
xhr.onload = function () {
console.log(xhr.response)
}
xhr.send()
webpack中间件解决跨域
- 首先要下载中间件webpack-dev-middleware
下载的插件如下:
在后端中添加如下代码:
const express = require('express')
const app = express()
const port = 3000
// CORS:后端解决跨域问题
// var allowCrossDomian = function(req,res,next){
// res.header("Access-Control-Allow-Origin", "*")
// res.header("Access-Contro-Allowl-Headers", "*")
// res.header("Access-Control-Allow-Methods", "*")
// next()
// }
// app.use(allowCrossDomian)
// 中间件,解决跨域问题
const webpack = require('webpack')
const middle = require('webpack-dev-middleware')
const complier = webpack(require('./webpack.config'))
app.use(middle(complier))
app.get('/user', function(req,res){
res.json({name : 'jack'})
console.log(123)
})
app.listen(port, () => console.log(`服务端已启动,端口号3000!`))
以上就是四种方法解决跨域问题,可能讲的不是特别清晰。
更多推荐
已为社区贡献3条内容
所有评论(0)