###### 前端:
Vue-cli 脚手架搭建前端项目:
前提 node已经安装过了。
创建前端项目:
> mkdir blog
> cd blog
> vue init webpack your-project-name
> Project name: // 这里小写 大写会会报错
> .....
我的项目用到了 vue-router 、EsLint ,当出现是否安装vue-router 、EsLint时,输入 yes
> // 根据提示
> cd your-project-name
> npm install 或 cnpm install
> npm run dev // 进入开发环境
接下来就可以愉快的Coding
前端目录结构:
- Frontend // 前端
+ build // 项目构建目录 Webpack 相关代码
+ config // 配置目录
/* + dist */ // 生产环境下,项目文件 执行 npm run build 会产生
+ node_modules // npm 加载的项目依赖模块目录
- src // 项目源文件目录
| - compontents // 组件目录
| | - common // 公共组件目录
| | | Article-detail.vue // 文章详情组件
| | | Footer.vue // 页脚组件
| | | Nav.vue // 导航组件
| | Articles.vue // 文章列表组件
| | Index.vue // 首页组件
| | Projects.vue // 项目列表组件
| - router
| index.js // 前端路由配置文件
| - sass // css预编译工具Sass,scss文件
| | _common.scss // 公共样式
| App.vue
| main.js
+ static // 静态文件 存放图片、字体文件等
.xxxx // babel 、 Eslint 、 git等 配置
index.html // 首页入口文件
package.json // 项目配置文件 项目依赖的相关插件包
package-lock.json // 锁定安装时的插件包的版本 即 npm install 时 安装指定版本致使项目得以运行
README.md // 项目说明文档
PS: 当我从我的github 克隆下来项目 运行开发环境时, 出现一堆错误 如: vue-loader 、css-loader 等等。
原因: 我的项目用到了Sass,webpack 没有默认安装Sass
解决: cnpm install --save node-sass 其次 cnpm install --save sass-loader
###### 后端:
前提 python3.6、Django1.10.7 安装好。
> django-admin startproject your-project-name
> django-admin startapp blog
目录结构:
- Backend // 后端项目名称
| - Backend
| | settings.py // 配置文件,模板路径配置,中间件配置等
| | urls.py // 后端路由配置
| | wsgi.py // scoket
| - blog // 程序应用目录
| | + migrations // 存放编译好数据库操作文件目录
| | __init__.py
| | admin.py // django 后台管理文件 注册模型、修改后台标题
| | apps.py // 应用程序配置文件
| | filter.py // 条件过滤
| | models.py // 模型文件
| | serializers.py // 序列化
| | test.py
| views.py // 视图文件,后端业务逻辑。
| manage.py // 命令行工具,用于django 交互
安装所需插件:
> pip install djangorestframework
> pip install markdown # Markdown support for the browsable API.
> pip install django-filter # Filtering support
修改settings.py 文件
// 添加插件到APPS
INSTALLED_APPS = [
......
'django.contrib.staticfiles',
'rest_framework',
'blog',
'django_filter',
]
// 连接本地数据库 mysql
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog', // 先在本地数据库创建该数据库
'USER': '****',
'PASSWORD': '*******',
'HOST': '',
}
}
// 设置django 后台 中文 、同步北京时间
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Beijing'
这时运行开发环境会报 No module named 'MySQLdb 错误
原因: python3连接MySQL不能再使用mysqldb,取而代之的是pymysql
解决: pip install pymysql 然后在 __init__.py下添加:
# __init__.py 文件
import pymysql
pymysql.install_as_MySQLdb()
至此,本地开发环境搭建完成。
当前端和后端都开发好了,那怎么前端如何向后端获取数据?
原因:同源策略限制,使两个不用域无法相互通信。
前端 http://localhost:8080/ 与 后端 http://127.0.0.1:8000/,端口不同,是两个不同的域。前端向不同域的后端请求的过程,叫跨域。
解决:
1. jsonp 跨域
原理:通过动态创建script标签,利用<script>的src 不受同源策略约束来跨域获取数据。
代码:
```
// demo.html
......
// 通过Ajax 调用接口
$.ajax({
async : true,
url : "https://xxx.com/v2/book/search",
type : "GET",
dataType : "jsonp", // 返回的数据类型,设置为JSONP方式
jsonp : 'callback', //指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
jsonpCallback: 'handleResponse', //设置回调函数名
data : {
q : "javascript",
count : 1
},
success: function(response, status, xhr){
console.log('状态为:' + status + ',状态是:' + xhr.statusText);
console.log(response);
}
});
```
2. document.domain
使用条件:
有其他页面 window 对象的引用。
二级域名相同。
协议相同。
端口相同。
```
// a.html
<body>
<iframe id='a' src='http://b.example.com/b.html' οnlοad='test()'>
</body>
<script type="text/javascript">
document.domain = 'example.com';
function test() {
alert(document.getElementById('a').contentWindow);
}
</script>
// b.html
<script type="text/javascript">
document.domain = 'example.com';
</script>
<body>
我是b.example.com的body
</body>
```
3. window.name
4. [postMessage](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage)
```
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用
message
将要发送到其他 window的数据
targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI
// 示例:
var popup = window.open(...popup details...);
// 如果弹出框没有被阻止且加载完成
// 这行语句没有发送信息出去,即使假设当前页面没有改变location(因为targetOrigin设置不对)
popup.postMessage("The user is 'bob' and the password is 'secret'",
"https://secure.example.net");
// 假设当前页面没有改变location,这条语句会成功添加message到发送队列中去(targetOrigin设置对了)
popup.postMessage("hello there!", "http://example.org");
function receiveMessage(event)
{
// 我们能相信信息的发送者吗? (也许这个发送者和我们最初打开的不是同一个页面).
if (event.origin !== "http://example.org")
return;
// event.source 是我们通过window.open打开的弹出页面 popup
// event.data 是 popup发送给当前页面的消息 "hi there yourself! the
secret response is: rheeeeet!
}
window.addEventListener("message", receiveMessage, false);
// 弹出页 popup 域名是<http://example.org>,以下是script标签中的代码:
// 当A页面postMessage被调用后,这个function被addEventListenner调用
function receiveMessage(event)
{
// 我们能信任信息来源吗?
if (event.origin !== "http://example.com:8080")
return;
// event.source 就当前弹出页的来源页面
// event.data 是 "hello there!"
// 假设你已经验证了所受到信息的origin (任何时候你都应该这样做), 一个很方便的方式就是把enent.source
// 作为回信的对象,并且把event.origin作为targetOrigin
event.source.postMessage("hi there yourself! the secret response " +
"is: rheeeeet!",
event.origin);
}
window.addEventListener("message", receiveMessage, false);
```
5. 跨域资源共享(CORS)
跨域资源共享是本项目最终的方案,简单、方便。
第一种:前端设置跨域请求, config文件夹下的index.js中的dev部分:
```
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://example.com/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
```
然后在main.js中设置全局属性:
```
Vue.prototype.HOST = '/api'
```
使用:
```
axios.get(this.HOST + 'xxx/xxx').then((res) => {
})
```
第二种:在后端(Django)设置跨域
```
// settings.py 文件 添加:
INSTALLED_APPS = [
...
]
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
```
Vue-cli 脚手架搭建前端项目:
前提 node已经安装过了。
创建前端项目:
> mkdir blog
> cd blog
> vue init webpack your-project-name
> Project name: // 这里小写 大写会会报错
> .....
我的项目用到了 vue-router 、EsLint ,当出现是否安装vue-router 、EsLint时,输入 yes
> // 根据提示
> cd your-project-name
> npm install 或 cnpm install
> npm run dev // 进入开发环境
接下来就可以愉快的Coding
前端目录结构:
- Frontend // 前端
+ build // 项目构建目录 Webpack 相关代码
+ config // 配置目录
/* + dist */ // 生产环境下,项目文件 执行 npm run build 会产生
+ node_modules // npm 加载的项目依赖模块目录
- src // 项目源文件目录
| - compontents // 组件目录
| | - common // 公共组件目录
| | | Article-detail.vue // 文章详情组件
| | | Footer.vue // 页脚组件
| | | Nav.vue // 导航组件
| | Articles.vue // 文章列表组件
| | Index.vue // 首页组件
| | Projects.vue // 项目列表组件
| - router
| index.js // 前端路由配置文件
| - sass // css预编译工具Sass,scss文件
| | _common.scss // 公共样式
| App.vue
| main.js
+ static // 静态文件 存放图片、字体文件等
.xxxx // babel 、 Eslint 、 git等 配置
index.html // 首页入口文件
package.json // 项目配置文件 项目依赖的相关插件包
package-lock.json // 锁定安装时的插件包的版本 即 npm install 时 安装指定版本致使项目得以运行
README.md // 项目说明文档
PS: 当我从我的github 克隆下来项目 运行开发环境时, 出现一堆错误 如: vue-loader 、css-loader 等等。
原因: 我的项目用到了Sass,webpack 没有默认安装Sass
解决: cnpm install --save node-sass 其次 cnpm install --save sass-loader
###### 后端:
前提 python3.6、Django1.10.7 安装好。
> django-admin startproject your-project-name
> django-admin startapp blog
目录结构:
- Backend // 后端项目名称
| - Backend
| | settings.py // 配置文件,模板路径配置,中间件配置等
| | urls.py // 后端路由配置
| | wsgi.py // scoket
| - blog // 程序应用目录
| | + migrations // 存放编译好数据库操作文件目录
| | __init__.py
| | admin.py // django 后台管理文件 注册模型、修改后台标题
| | apps.py // 应用程序配置文件
| | filter.py // 条件过滤
| | models.py // 模型文件
| | serializers.py // 序列化
| | test.py
| views.py // 视图文件,后端业务逻辑。
| manage.py // 命令行工具,用于django 交互
安装所需插件:
> pip install djangorestframework
> pip install markdown # Markdown support for the browsable API.
> pip install django-filter # Filtering support
修改settings.py 文件
// 添加插件到APPS
INSTALLED_APPS = [
......
'django.contrib.staticfiles',
'rest_framework',
'blog',
'django_filter',
]
// 连接本地数据库 mysql
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog', // 先在本地数据库创建该数据库
'USER': '****',
'PASSWORD': '*******',
'HOST': '',
}
}
// 设置django 后台 中文 、同步北京时间
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Beijing'
这时运行开发环境会报 No module named 'MySQLdb 错误
原因: python3连接MySQL不能再使用mysqldb,取而代之的是pymysql
解决: pip install pymysql 然后在 __init__.py下添加:
# __init__.py 文件
import pymysql
pymysql.install_as_MySQLdb()
至此,本地开发环境搭建完成。
当前端和后端都开发好了,那怎么前端如何向后端获取数据?
原因:同源策略限制,使两个不用域无法相互通信。
前端 http://localhost:8080/ 与 后端 http://127.0.0.1:8000/,端口不同,是两个不同的域。前端向不同域的后端请求的过程,叫跨域。
解决:
1. jsonp 跨域
原理:通过动态创建script标签,利用<script>的src 不受同源策略约束来跨域获取数据。
代码:
```
// demo.html
......
// 通过Ajax 调用接口
$.ajax({
async : true,
url : "https://xxx.com/v2/book/search",
type : "GET",
dataType : "jsonp", // 返回的数据类型,设置为JSONP方式
jsonp : 'callback', //指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
jsonpCallback: 'handleResponse', //设置回调函数名
data : {
q : "javascript",
count : 1
},
success: function(response, status, xhr){
console.log('状态为:' + status + ',状态是:' + xhr.statusText);
console.log(response);
}
});
```
2. document.domain
使用条件:
有其他页面 window 对象的引用。
二级域名相同。
协议相同。
端口相同。
```
// a.html
<body>
<iframe id='a' src='http://b.example.com/b.html' οnlοad='test()'>
</body>
<script type="text/javascript">
document.domain = 'example.com';
function test() {
alert(document.getElementById('a').contentWindow);
}
</script>
// b.html
<script type="text/javascript">
document.domain = 'example.com';
</script>
<body>
我是b.example.com的body
</body>
```
3. window.name
4. [postMessage](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage)
```
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用
message
将要发送到其他 window的数据
targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI
// 示例:
var popup = window.open(...popup details...);
// 如果弹出框没有被阻止且加载完成
// 这行语句没有发送信息出去,即使假设当前页面没有改变location(因为targetOrigin设置不对)
popup.postMessage("The user is 'bob' and the password is 'secret'",
"https://secure.example.net");
// 假设当前页面没有改变location,这条语句会成功添加message到发送队列中去(targetOrigin设置对了)
popup.postMessage("hello there!", "http://example.org");
function receiveMessage(event)
{
// 我们能相信信息的发送者吗? (也许这个发送者和我们最初打开的不是同一个页面).
if (event.origin !== "http://example.org")
return;
// event.source 是我们通过window.open打开的弹出页面 popup
// event.data 是 popup发送给当前页面的消息 "hi there yourself! the
secret response is: rheeeeet!
}
window.addEventListener("message", receiveMessage, false);
// 弹出页 popup 域名是<http://example.org>,以下是script标签中的代码:
// 当A页面postMessage被调用后,这个function被addEventListenner调用
function receiveMessage(event)
{
// 我们能信任信息来源吗?
if (event.origin !== "http://example.com:8080")
return;
// event.source 就当前弹出页的来源页面
// event.data 是 "hello there!"
// 假设你已经验证了所受到信息的origin (任何时候你都应该这样做), 一个很方便的方式就是把enent.source
// 作为回信的对象,并且把event.origin作为targetOrigin
event.source.postMessage("hi there yourself! the secret response " +
"is: rheeeeet!",
event.origin);
}
window.addEventListener("message", receiveMessage, false);
```
5. 跨域资源共享(CORS)
跨域资源共享是本项目最终的方案,简单、方便。
第一种:前端设置跨域请求, config文件夹下的index.js中的dev部分:
```
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://example.com/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
```
然后在main.js中设置全局属性:
```
Vue.prototype.HOST = '/api'
```
使用:
```
axios.get(this.HOST + 'xxx/xxx').then((res) => {
})
```
第二种:在后端(Django)设置跨域
```
// settings.py 文件 添加:
INSTALLED_APPS = [
...
]
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
```