东莞企业推广网站,遵义 网站建设,优化设计五年级下册语文答案2021,手机怎样下载安装建设银行网站文章目录 一、跨域二、JSONP实现跨域请求三、前端代理实现跨域请求四、后端设置请求头实现跨域请求五、Nginx代理实现跨域请求5.1 安装Nginx软件5.2 使用Ubuntu安装nginx 本文是在学习课程满神yyds后记录的笔记#xff0c;强烈推荐读者去看此课程。
一、跨域
出于浏览器的同… 文章目录 一、跨域二、JSONP实现跨域请求三、前端代理实现跨域请求四、后端设置请求头实现跨域请求五、Nginx代理实现跨域请求5.1 安装Nginx软件5.2 使用Ubuntu安装nginx 本文是在学习课程满神yyds后记录的笔记强烈推荐读者去看此课程。
一、跨域
出于浏览器的同源策略限制浏览器会拒绝跨域请求。
什么是同源策略
请求的时候拥有相同的协议、域名、端口只要有一个不同就属于跨域。
主机(http://www.small5.com)是否跨域原因https://www.small5.com是协议不同 http和httpshttp://www.small5.com:8001是端口不同 80 和 8001http://www.baidu.com是域名不同 small5和百度http://www.small5.com/index.html否协议、端口、域名全部相同
跨域的四种解决方案
前后端协商jsoup前端解决 使用代理dev后段解决 设置请求头运维端解决 nginx代理
二、JSONP实现跨域请求
jsonp解决跨域的原理是由于script标签的src属性不受同源策略的限制可以跨域请求到服务器端的资源并且把资源作为脚本(js)来运行因此可以解决跨域。
img属性也有src属性但是它只是把服务器的资源返回并没有进一步做任何js的动作。
但是jsonp解决跨域存在一个限制它只能发送get请求。
JSONP解决跨域的基本工作原理
前端定义一个回调函数该函数将处理从服务器返回的数据前端创建一个script标签并将跨域请求的url作为script标签的src属性值在url中需要包含一个特殊的参数该参数用来告知服务器回调函数的名称后端服务器会通过query拿到回调函数名。服务器接收到请求后解析url参数通过query拿到回调函数名并响应请求将要发送的数据作为参数传入回调函数返回前端【使用模板字符串调用前端函数】前端接收到响应后由于脚本标签生成的script元素的src属性已经指向了服务器返回的脚本url浏览器会自动执行该脚本从而调用前端所定义的回调函数并将服务器返回的数据作为参数传入。
可以看出使用JSONP解决跨域需要前后端相互配合实现。
下面我们通过代码实现JSONP实现跨域访问: 前端html
!DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titlejsonp实现跨域/title
/headbodyscript// jsonp函数实现了跨域访问其中包括1.定义script并设置src传递回调函数名 2.前端window中动态定义回调函数// name表示回调函数名const jsonp (name) {// 2.前端创建一个script标签并将跨域请求的url作为script标签的src属性值// 在url中需要包含一个特殊的参数该参数用来告知服务器回调函数的名称后端服务器通过query拿到回调函数名let script document.createElement(script)script.src http://localhost:3000/api/jsonp?callback name // 将回调函数名传递给服务器document.body.appendChild(script)return new Promise((resolve) {// 1.前端动态定义一个回调函数该函数将处理从服务器返回的数据window[name] (data) { // data是后端调用前端回调函数返回的数据// 4. 返回服务器返回的数据resolve(data)}console.log(window);})}// 调用jsonp方法// 这里的回调函数名为callback加时间戳 使用时间戳的原因是避免函数重名jsonp(callback${new Date().getTime()}).then(res {// 输出服务器返回的数据console.log(res);})/script
/body/html后端使用nodeindex.js
const express require(express)const app express()
// 发送get请求
app.get(/api/jsonp, (req, res) {// 3. 服务器接收到请求后解析url参数通过query拿到回调函数名并发送请求将要发送的数据作为参数传入回调函数const { callback } req.query// 后端响应请求并返回数据// 注意这里以模板字符串的形式返回数据实现调用前端的回调函数传递了值为hello small5的参数并执行这个前端回调函数// 实际上这个参数的内容才是真实响应数据改变参数内容前端收到的数据也随之改变res.send(${callback}(hello small5))
})app.listen(3000, () {console.log(server is running);
})运行端口为3000的服务器 通过Live Server运行html文件Live Server会自动开一个5500的端口这和服务器端口不一致因此是存在跨域的。 通过上图可以看到使用JSONP实现跨域请求的请求结果状态码是200表示请求成功并响应结果这表明使用JSONP成功实现了跨域请求。
下面我们来看看请求传递的参数和响应结果以验证 可以看到前端成功传递参数值为callback时间戳的回调函数名、参数名为callback的参数以及响应结果是调用此回调函数并传参。
下面我们再看看前端输出的请求结果 可以看到前端成功接收响应的数据下面我们通过输出的window来验证是否有一个名为callback时间戳的回调函数 可以看到完全符合预期前端确实存在名为callback时间戳的回调函数。
以上就是JSONP实现跨域请求的所有内容。
三、前端代理实现跨域请求
前端使用代理来实现跨域请求需要借助前端构建工具如webpack、rollup、vite之类构建工具通过在配置文件中配置代理实现拦截请求并转发到指定服务器上。
这里我以vite来举例
使用npm i vite -D安装vite并在根目录新建vite.config.js文件。 vite.config,js
import { defineConfig } from viteexport default defineConfig({server: {proxy: {/api: {target: http://localhost:3000,changeOrigin: true, // changeOrigin表示是否改变请求的源// rewrite: (path)path.replace(/^\/api/, ) // rewrite表示重写请求路径这里的示例实现了匹配到/api/则替换为空}}}
})node配置服务器index.js
const express require(express)const app express()// 返回json数据的get请求
app.get(/api/json, (req, res) {res.json({name: small5})
})app.listen(3000, () {console.log(server is running);
})html文件发送请求:index.html
!DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titlejsonp解决跨域/title
/headbodyscript// Fetch 是一个基于 promise 的用于浏览器和 node.js 的 HTTP 客户端// 它能够轻松的将请求发送到服务器并得到响应。// Fetch 使用方式简单又能充分发挥出 Promise 的特性是越来越多人使用的发起请求的方式之一。fetch(/api/json).then(res res.json()).then(res {console.log(res);})/script
/body/html这里我们就不能使用Live Server运行html文件了需要配置一下pacage.json文件使用vite运行html文件。
{scripts: {dev: vite},dependencies: {express: ^4.17.1,express-session: ^1.17.3,},devDependencies: {vite: ^4.4.8}
}现在我们使用npm run dev命令运行 可以看到vite自动开了url为http://127.0.0.1:5173客户端域名这和node后端定义的http://localhost:3000是存在跨域的。查看请求结果如下 可以看到状态码200表示成功实现了跨域请求再看看接口响应结果和前端得到的请求结果 成功得到node后端返回的结果这表明成功实现前端代理实现跨域请求。
四、后端设置请求头实现跨域请求
接口设置请求头
// 返回json数据的get请求
app.get(/api/json, (req, res) {// res.setHeader(Access-Control-Allow-Origin, *) 任何请求都能跨域 不安全res.setHeader(Access-Control-Allow-Origin, http://127.0.0.1:5500) // 指定某个请求能跨域res.json({name: small5})
})五、Nginx代理实现跨域请求
由于本人对于Ubuntu不太了解因此这里主要讲解一下使用Ubuntu安装nginx并实现跨域请求
5.1 安装Nginx软件
安装完成后在nginx,conf配置代理
5.2 使用Ubuntu安装nginx
在Microsoft Store中安装对应的Ubuntu我安装的是以下版本。
下载完成后启动Ubuntu可能会报错解决方式参考Ubuntu 20.04.4 LTS 报错解决方案。
Ubuntu正常启动后输入apt-get install nginx安装nginx如果报没有权限的错误解决这个问题需要以root用户身份或具有sudo权限的用户身份运行命令。可以尝试在命令前加sudo。 安装完成后再次输入命令验证安装结果得到如下结果表示安装成功 接着我们打开资源管理器找到Linux目录安装的nginx默认是在ect文件夹下 nginx的默认配置文件是在sites-avaliable文件夹下 下面我们打开默认配置文件找到默认服务配置的server配置一个代理。 注意使用nginx配置代理不能使用localhost必须使用Windows主机的ip打开Ubuntu输入cat /etc/resolv.conf可以获取到主机ip。 我们可以验证一下使用Windows主机ip能否请求成功接口。
下面我们配置好后端node接口并启动服务器如下图 在Ubuntu上使用命令curl http://主机IP:服务器端口号/接口地址发送请求。
想了解curl命令可以查看博客技术分享 | 使用 cURL 发送请求 可以看到返回正确结果接口发送成功这表明使用Windows主机ip作为代理域名是没有问题的。
验证Windows主机ip地址作为代理域名没有问题后我们再使用Windows主机ip在nginx配置文件中配置代理如下 这里我遇到一个问题不管是使用记事本还是vscode打开配置文件再修改编辑后保存会无法保存尝试了好几次都保存不了后面我是通过在Ubuntu的Linux系统中使用vim编辑器打开配置文件然后修改保存这其中又遇到一个问题如果没有加sudo权限的话执行vim 配置文件路径打开后修改文件保存会报此文件是只读文件不允许修改因此要在指令前加sudo提供sudo权限后选择输入E进入编辑修改后保存可以看到配置文件成功被修改了。
关于vim编辑器的基本使用可以查看我的博客git的基本使用中的预备知识那节内容。 接着我们在Ubuntu中输入nginx启动nginx我这里没有权限添加了sudo后才启动成功另外由于配置文件的location拼写错误还报错了一次。如下 接着在浏览器地址栏输入localhost:80回车得到如下页面表示nginx启动成功 下面就不再nginx写代码了直接在开发者工具内发送请求验证是否实现跨域请求是一样的。 通过查看请求状态码可以验证成功实现了跨域请求
使用nginx代理实现跨域适合项目上线时使用因此这种方式使用非常普遍。
以上就是使用nginx代理实现跨域请求的全部内容了。