node.js结合前端进行跨域问题的解决方法:
1.node.js运用http.get()方法在后端请求数据:
1.1前端ajax请求
$.ajax({
url: 'http://localhost:8080/',
success: (result) => {
console.log(result)
}
})
1.2node.js的用法
node.js天生自带http和https模块,因为node.js天生不跨域,所以可以请求数据然后发送给前端,帮助前端实现跨域的解决。
1.3node.js代码
var http = require('http')
var https = require('https')//引用http和https模块
const server = http.createServer((request, response) => {
//创建一个server服务,给前端提供一个接口
var url = request.url.substr(1)
var data = ''
response.writeHeader(200, {
'content-type': 'application/json;charset=utf-8',
'Access-Control-Allow-Origin': '*'
})//因为我在node.js是用8080接口所以前端请求会跨域,加上这个解决前端和node跨域问题,https.get(`https://m.lagou.com/listmore.json${url}`, (res) => {
res.on('data', (chunk) => {
data += chunk
})
//data为请求回来的数据,如果直接返回chunk会输出一个<Buffer>的东西
res.on('end', () => {
response.end(JSON.stringify({//返回数据给前端
ret: true,
data
}))
})
})
})
server.listen(8080, () => {
console.log('localhost:8080')
})//node.js开启的服务端口为8080
2.基于get请求的改进:
上述是前端请求get请求,那不能避免前端会使用post请求,post请求怎么弄?
如果不获取发送的数据,写法和上面的get请求一样,我们直接来看拿数据做判断的情况
2.1前端配置
$.ajax({
url: 'http://localhost:8080/api/login',
type: 'POST',
data: {
username: 'abc',
password: 123
},
success: (result) => {
console.log(result)
}
})
2.2node.js的代码
const http = require('http')
const url = require('url')
const querystring = require('querystring')
const app = http.createServer((req, res) => {
//我们要根据前端的data来返回数据,怎么获取前端的data呢?我们想到后端请求数据的时候可以res.on('data'(chunk)=>{})拼接字符串来获取,那么前端的数据那?我们也可以写类似的但是要用req操作了。
let data = ''
let urlObj = url.parse(req.url, true)
res.writeHead(200, {
'content-type': 'application/json;charset=utf-8',
'Access-Control-Allow-Origin': '*'
})
req.on('data', (chunk) => {
data += chunk
})
//data的数据username=abc&password=123,我们可以用querystring.parse转换成对象
req.on('end', () => {
console.log(data)
responseResult(querystring.parse(data))
})//获取前端post数据
function responseResult(data) {
switch (urlObj.pathname) {
case '/api/login':
res.end(JSON.stringify({
message: data
}))
break
default:
res.end('404.')
break
}
}
})
app.listen(8080, () => {
console.log('localhost:8080')
})
前端输出
{message: {…}}
message: {username: "abc", password: "123"}
__proto__: Object
当然这只是一个能够获取前端post请求的一个小栗子,你也可以对post请求的数据做判断返回不同的数据!
3.jsonp的请求原理:
运用了script标签不跨域的解决方法,可能需要后端的cb函数配合实现
3.1 前端请求代码
<script src="http://localhost:8080/api/user"></script>//就一个script的请求
3.2node.js辅助代码
const http = require('http')
const url = require('url')
const app = http.createServer((req, res) => {
let urlObj = url.parse(req.url, true)
switch (urlObj.pathname) {
case '/api/user':
res.end(`console.log(0)`)
break
default:
res.end('404.')
break
}
})
app.listen(8080, () => {
console.log('localhost:8080')
})
//其中url.parse可以把地址转换成一个对象,第二个参数可以把里面的query转化成对象所以urlobj如下
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?cb=callback',
query: { cb: 'callback' },
pathname: '/api/user',
path: '/api/user?cb=callback',
href: '/api/user?cb=callback' }
这时候前端通过script标签发送一个请求,node.js拦截解析出pathname,选择对应的case,给前端返回一个console.log(0),前端返回立刻执行。那如果前端有一个cb函数,那是不是node返回当前函数会立刻执行?
3.3改进:
前端请求:
<script>
function callback(data) {
console.log(data)
}
</script>
<script src="http://localhost:8080/api/user?cb=callback"></script>
node的部分改变;
case '/api/user':
res.end(`${urlObj.query.cb}({"name": "gp145"})`)
break
前端输出{name: “gp145”},这样前端通过不同的cb函数就可以跟后端请求不同的数据,这时候就能明白,原来后端做了类似于这样的事情
4.类似于nginxt代理的方法:
node可以通过反向代理的方法把当前网站代理成目标网站
4.1前端请求代码
$.ajax({
url: 'http://localhost:8080/api',
success: (result) => {
console.log(result)
}
})
4.2node.js的代码
const http = require('http')
const proxy = require('http-proxy-middleware')
//反向代理的插件,npm i http-proxy-middleware
http.createServer((req, res) => {
let url = req.url
res.writeHead(200, {
'content-type': 'application/json;charset=utf-8',
'Access-Control-Allow-Origin': '*'
})
//还是给前端返回一个接口。。。毕竟写的不好
if (/^\/api/.test(url)) {
let apiProxy = proxy('/api', {
target: 'https://m.lagou.com',
//target 代理这个网站,怎么代理??当你输入/api时候,网站自动识别就知道你代理了这个网站
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
//路径重写 我们写的连接肯定有/api这个暗号,但是人家的路径里面没有/api所以我们可以通过pathRewrite吧/api删除
})
apiProxy(req, res)
// http-proy-middleware 在Node.js中使用的方法,把数据返回给前端,必须写要不前端没数据
} else {
switch (url) {
case '/index.html':
res.end('index.html')
break
case '/search.html':
res.end('search.html')
break
default:
res.end('[404]page not found.')
}
}
}).listen(8080)
在上述四个方法中第一个、第二个、第四个node.js只是处于前端和后端的中间层,讲述了node.js怎么根据前端给的东西向后端拿东西,并且不跨域。第三个node.js扮演的是后端的角色。通过这四个方法我们更清楚node.js所处位置和实现的功能以及解决跨域的四个方法;
我的理解是这样的。。。如果有什么不对还望指出,我还是个小学生,