node

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所处位置和实现的功能以及解决跨域的四个方法;
我的理解是这样的。。。如果有什么不对还望指出,我还是个小学生,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值