JavaScript学习笔记(七) 跨域问题

简介: JavaScript学习笔记(七) 跨域问题


1、跨域问题


(1)什么是跨域问题?


什么是域?一个域由协议、域名、端口三者共同组成


什么是跨域?只要协议、域名、端口三者任意一个不同,就当作是跨域


什么是跨域问题?简单来说,就是 浏览器 不允许跨域请求资源


(2)为什么会有跨域问题?


为什么会有跨域问题?这是因为浏览器同源策略的限制


什么是同源策略?同源策略限制一个源加载的文档或脚本如何与来自另一个源的资源进行交互


为什么会有同源策略?它是一种重要的安全机制,用于隔离潜在的恶意文件


(3)为什么还要跨域请求?


既然说跨域请求会带来安全问题,那么为什么我们还要进行跨域请求呢?


这个也是莫得办法呀,有的时候同一家公司会有多个不同的子域,需要相互请求资源


2、跨域问题的解决方案


(0)准备环境


我们先来搭建一个简单的测试环境,整体的文件结构如下:

+ back_end
  + node_modules
  - package-lock.json
  - package.json
  - server.js
+ front_end
  + node_modules
  - index.vue
  - package-lock.json
  - package.json


① 后端部分【Node.js + Express】


在 back_end 目录下运行 npm init 命令,创建 package.json 文件


接着使用 npm install --save express 命令安装 express


然后创建一个名为 server.js 的文件,在文件中输入以下内容:


// 引入 express 模块
const express = require('express')
// 创建 express 实例
var app = express()
// 设置路由
app.get('/api', function(req, res) {
    // console.log(req.query.message)
    res.json({
        'message': req.query.message
    })
})
app.get('/', function(req, res) {
    res.send('Hello World')
})
// 启动服务器,监听端口 5000
var server = app.listen(5000)

命令行运行 node server.js 启动 express 服务器(127.0.0.1:5000


② 前端部分【Vue + jQuery】


同样在 front_end 目录下运行 npm init 命令,创建 package.json 文件


接着使用 npm install --save jquery 命令安装 jquery


使用 npm install -g @vue/cli 命令全局安装 Vue


使用 npm install -g @vue/cli-service-global 命令全局安装一个拓展


然后创建一个名为 index.vue 的文件,在文件中输入以下内容:

<template>
    <div>
        <input class="enter-message" v-model="message" />
        <button class="send-message" v-on:click="submit">Submit</button>
    </div>
</template>
<script>
import $ from 'jquery'
import qs from 'qs'
export default {
    data: function () {
        return {
            message: 'Hello'
        }
    },
    methods: {
        submit: function() {
            let params = qs.stringify({
                'message': this.message
            })
            $.ajax({
                type: 'GET',
                url: 'http://127.0.0.1:5000/api' + '?' + params,
                success: function(value) {
                    console.log('success')
                    console.log(value)
                },
                error: function(error) {
                    console.log('error')
                    console.log(error)
                },
            })
        }
    }
}
</script>
<style>
.enter-message {
    display: block;
    margin: 20px;
    padding: 2px;
}
.send-message {
    display: block;
    margin: 20px;
}
</style>


命令行运行 vue serve index.vue 快速启动一个服务器(127.0.0.1:8080),搭载应用


③ 测试


由于两者端口不同,所以毫无疑问的出现了跨域问题

792b8033266c367c2832890a780cfeb9_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzbXJ6eA==,size_16,color_FFFFFF,t_70#pic_center.png

下面我们讨论两种常见的跨域问题解决方案,先摆上最终效果

c9223185248cbe09525496f672e22f04_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzbXJ6eA==,size_16,color_FFFFFF,t_70#pic_center.png



(1)JSONP


简单来说,JSONP 通过 <script> 标签的 src 属性不受同源策略的限制获取跨域资源


具体来说,前端在参数中发送一个回调函数的函数名,后端返回这个函数的调用,并把数据放在这个函数的参数上


注意,JSONP 只支持 GET 方法,前后端的核心代码如下


后端代码:

app.get('/api', function(req, res) {
    let func = req.query.callback
    let data = { 'message': req.query.message }
    res.send(func + '(' + JSON.stringify(data) + ')')
})

前端代码:

methods: {
    submit: function() {
        let url = 'http://127.0.0.1:5000/api'
        let data = { 'message': this.message }
        this.jsonp(url, data).then(function(res) {
            console.log(res)
        })
    },
    jsonp: function(url /*String*/, data /*Object*/) {
        return new Promise(function(resolve, reject) {
            window.handleResponse = function(result) {
                resolve(result)
            }
            let script = document.createElement('script')
            script.type = 'text/javascript'
            script.src = url + '?' + qs.stringify(data) + '&callback=handleResponse'
            document.getElementsByTagName('head')[0].appendChild(script)
            setTimeout(function() {
                document.getElementsByTagName('head')[0].removeChild(script)
            }, 1000)
        })
    }
}


实际上,Node.js 和 jQuery 都提供了更加便捷的方式使用 JSONP,前后端的核心代码如下


后端代码:


app.get('/api', function(req, res) {
    res.jsonp({ // 改成 jsonp
        'message': req.query.message
    })
})


前端代码:

methods: {
    submit: function() {
        let params = qs.stringify({
            'message': this.message
        })
        $.ajax({
            type: 'GET',
            url: 'http://127.0.0.1:5000/api' + '?' + params,
            dataType: "jsonp", // 指定 jsonp
            success: function(value) {
                console.log(value)
            },
            error: function(error) {
                console.log(error)
            },
        })
    }
}



(2)CORS


跨域资源共享(Cross-Origin Resource Sharing,CORS)是 W3C 中定义的标准


它定义了在跨域请求资源时,浏览器与服务器如何进行交互,它们通过 HTTP 头部传达这种信息


我们只需要修改后端返回的 Response 的 HTTP 头部即可,前端代码无需修改


后端代码:

app.get('/api', function(req, res) {
    res.header('Access-Control-Allow-Origin', '*') // 加上 HTTP 头部即可
    res.json({
        'message': req.query.message
    })
})

目录
相关文章
|
2天前
|
JSON JavaScript 前端开发
js跨域实现
【10月更文挑战第31天】在实际开发中,需要根据具体的需求和项目情况选择合适的跨域解决方案。
8 1
|
2月前
|
JavaScript 前端开发 API
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
|
1月前
|
JavaScript 前端开发
【干货分享】JavaScript学习笔记分享
【干货分享】JavaScript学习笔记分享
52 0
|
2月前
|
Web App开发 前端开发 JavaScript
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
|
6月前
|
JSON JavaScript 前端开发
【JavaScript技术专栏】JavaScript的跨域通信方法
【4月更文挑战第30天】本文探讨了JavaScript中的跨域通信方法,包括:同源策略和跨域通信的概念,以及JSONP、CORS、WebSockets、`window.postMessage()`、代理服务器和WebAssembly的使用。这些技术各有优劣,适用于不同的场景,是Web开发者解决跨域问题的关键工具。随着Web技术的演进,跨域通信的解决方案也将不断更新。
131 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
38 0
|
6月前
|
JavaScript 索引
用原生js的postMessage实现iframe传值,也可以用于跨域嵌套iframe传值
用原生js的postMessage实现iframe传值,也可以用于跨域嵌套iframe传值
用原生js的postMessage实现iframe传值,也可以用于跨域嵌套iframe传值
|
4月前
|
JavaScript
JS【实战】跨域的网页链接跳转
JS【实战】跨域的网页链接跳转
58 0
|
4月前
|
前端开发 JavaScript API
js【详解】ajax (含XMLHttpRequest、 同源策略、跨域、JSONP)
js【详解】ajax (含XMLHttpRequest、 同源策略、跨域、JSONP)
51 0
|
6月前
|
JSON JavaScript 前端开发
vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?
vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?
199 1