记住用户名密码
跨域
跨域就是请求的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> <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> <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' }) ] }
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!`))
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()
在后端中添加如下代码:
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!`))
以上就是四种方法解决跨域问题。
目前有 0 条留言 其中:访客:0 条, 博主:0 条