文档章节

一个后端的前端学习之旅——3.喜闻乐见的跨域问题

duoduo3_69
 duoduo3_69
发布于 2016/02/04 18:56
字数 1564
阅读 426
收藏 12

决定js框架

在写完 一个后端的前端学习之旅——1.决定学什么 后我决定用coffeescript来看一些js框架,本来想用react,结果发现用它跟gulp配起来略烦,选来选去选择了小半天决定最终用 spinejs, 看起来比较小,而且源码有coffee和js两个版本,还方便看,当然我知道这不是什么主流框架,可能文档什么的少一些,但这样更可以看出看源码的重要性,无论是不是python。

好的,开始学习

首先脚手架的项目就丢到一边,基于脚手架建了一个项目 leaning-frontend, 由于我把bower,npm的安装文件放到git中管理,项目比较大,github传输太慢了,先放着开源中国的git上。

然后bower装了下spine,npm装了下spine,我知道bower装的东西会被gulp编译到vendor.js里面,然而貌似我不用npm装spine的话在coffee里面会require报错(我暂时没有管require到底干毛的,看起来是import),bower装的spine有个问题,因为gulp中采用了一个main-bower-file还是什么东西的找包的主文件,然后gulp讲这个文件粘贴到vendor.js里面,但是看起来spine是模块分离的,需要单独引用(或者是其他什么原因),它并没有bower.json。所以我修改了下gulp中的tasks/bower.coffee将所有的外部库丢到一个文件夹里面这样可以直接引用(有没有更好的方案之后再说)。

第一步目录结构

spine是mvc的,然而都是js,所以我在source下面建了controllers、models、views这三个文件夹,views里面采用eco这么种东西,看起来很像djang的模板。

文档

class Contact extends Spine.Model
  @configure "Contact", "name"
  @extend Spine.Model.Ajax

  @url: "/users
  
  
class App extends Spine.Controller
  constructor: ->
    super
    # Instantiate other controllers..
    Photo.fetch()      

根据这个文档我知道了继承Model后@extend一个Spine.Model.Ajax然后添加一个url就可以调用Model.fetch()了,so我在main.coffee里面试了一下然后就出了些事情,容我慢慢道来。

我准备用学堂在线的某些api做一些事情: http://www.xuetangx.com/api/v2/courses,下面是我的Model。

class Course extends Spine.Model
  @configure "Course", "name"
  @extend Spine.Model.Ajax
  @url: "/api/v2/courses"

module.exports = Course

fecth调用的时候首先404了,因为gulp在dev时启动的是一个localhost的本地服务器(改成0.0.0.0:3000了), spine在请求的时候url是相对路径所以拼上的,好的吧,那我写绝对路径 @url: http://www.xuetangx.com/api/v2/courses, 然而他依然是拼接的(http://192.168.9.191:3000/http://www.xuetangx.com/api/v2/courses),我丢你老母。

然后继续看文档发现了 Spine.Model.host = "http://my-endpoint",强行把host设走,我就在main.coffee第一行把host设置了学堂在线的host,然后 就跨域了

喜闻乐见的跨域问题

首先我们知道,跨域是浏览器的某种安全限制,服务器端发起request并不存在跨域问题(这也是你可以愉快的用脚本requests.get或者写爬虫的原因)。 解决跨域问题有很多方案:

  1. 如果外域本来就是你的,并且你觉得允许所有人访问的话(一般不用,出发你就是一个专门的api服务器),nginx配上三行代码即可(一搜就有)
  2. 同1,只是不是nginx上加,而是在代码里面做一些事情,例如django,用django-cors-headers
  3. chrome可以关闭跨域 启动的时候加上一个参数即可C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe --disable-web-security
  4. 写一个proxy,这样你就有了1 2两点的条件随便搞

我选择的是4+2

proxy server

根据上面的方案选择我在项目根目录用django建了一个simple_server

cd 你的项目位置/leaning-frontend/simple_server
pip install -r requirements.txt # 如果你懂python请用virtualenv什么的
./manage.py runserver 0.0.0.0:12345 # 12345是你想运行的端口号

讲解

urls.py, 只有一个url所有的请求都用CrossDomainAjaxView来处理

url(r'^(?P<request_url>.*)$', CrossDomainAjaxView.as_view(), name='ajax-hanler')

views.py, 这个view是做这么一件事情的,将请求的url通过requests这个三方库在我的服务器端请求外域服务器,然后讲response转变成django的response来返回给前端,暂时只写了get(非get django要穿csrf什么的比较烦)。这里有件事情想讲一下:

  1. 请求的header,我本来是想把接受到的所有header丢给requests的然而获取不到数据,暂时不管;

  2. response的header,我本来也是想把所有的response header都带回来的,然而并不行,python级别的东西报了一个http 1.1有关的异常is_hop_by_hop,所以我也暂时没带过来。

  3. rest framework仅仅是我想用他的view支持下非get post请求(然而我并没做具体处理,实际上没有任何作用)

    -- coding: utf-8 --

    #from rest_framework.views import View #from rest_framework.generics import GenericAPIView as View from django.views.generic import View from django.conf import settings from simple_server.utils import get_request_header, get_request_headers from urlparse import urljoin from django.http.response import HttpResponse from wsgiref.util import is_hop_by_hop

    import requests

    class CrossDomainAjaxView(View):

    def transform_request_data(self, request, request_url):
        cross_domain_host = get_request_header(request, 'cross_domain_host') or settings.CROSS_DOMAIN_HOST
        url = urljoin(cross_domain_host, request_url)
        headers = get_request_headers(request)
        data = dict(request.GET)
        data.update(dict(request.POST))
        request_data = {
            'cross_domain_host': cross_domain_host,
            'url': url,
            'data': data,
            'headers': headers,
        }
        return request_data
    
    def transform_response(self, requests_response):
        response = HttpResponse(requests_response.content, content_type=
                requests_response.headers.get('Content-Type', 'text/plain'))
        return response
    
    
    def get(self, request, request_url):
        request_data = self.transform_request_data(request, request_url)
        response = requests.get(request_data['url'], request_data['data'])
                #headers=request_data['headers'])
        print response.content
        return self.transform_response(response)
    

settings.py

middleware加上这两个来允许跨域'corsheaders.middleware.CorsMiddleware'CORS_ORIGIN_ALLOW_ALL = True, 然后由于前端传的是相对路径所以我加了一个host CROSS_DOMAIN_HOST = 'http://www.xuetangx.com', get的时候支持在header里面改变不同的host支持不同网站的api调用而不是写死一个。

well done

chrome的Network的XHR里面这次看到请求了,哇哈哈拦路虎解决。

oh对了,顺便fix了一些gulp对于spine需要支持的东西,主要是eco。

btw,发现学堂在线一个交互做的不错的页面 (好吧其实是产品强行让我贴的友链,各位随意)

© 著作权归作者所有

duoduo3_69
粉丝 89
博文 57
码字总数 83746
作品 0
青岛
程序员
私信 提问
加载中

评论(0)

一个后端的前端学习之旅——3.喜闻乐见的跨域问题

决定js框架 在写完 一个后端的前端学习之旅——1.决定学什么 后我决定用coffeescript来看一些js框架,本来想用react,结果发现用它跟gulp配起来略烦,选来选去选择了小半天决定最终用 spinej...

D咄咄
2017/11/29
0
0
通过共享文件夹来进行前后端独立开发

最近在快速开发一个后台系统,前端使用了bootstrap和angular搭建,后端使用Java,由于前端采用的是单页富应用的Web App的构建方式,所以不适合做JSP页面,最后采用了【前端+ajax+后台】的前后...

前端届的科比
2015/11/18
101
0
前后端分离 | 关于登录状态那些事

背景 登录是一个网站最基础的功能。有人说它很简单,其实不然,登录逻辑很简单,但涉及知识点比较多,如: 密码加密、cookie、session、token、JWT等。 我们看一下传统的做法,前后端统一在一...

小忽悠
2018/10/12
0
0
云音乐小程序管理系统(四)——歌单列表前后端交互与跨域问题

让我们的后端获取到的歌单信息,在我们前端VUE框架上显示出来。 前后端分离交互 所以我们前端要发送一个请求 使用request中封装的来发送请求 获取地址,进行数据请求。 在我们的文件中引用请...

科技渣渣
03/31
0
0
Flask连接数据库打怪升级之旅

前言 在初学 Flask 的时候,在数据库连接这部分也跟每个初学者一样。但是随着工作中项目接手的多了,代码写的多了,历练的多了也就有了自己的经验和技巧。在对这块儿代码不断的进行升级改造后...

xjtuhit
2017/08/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

过拟合问题

本文作者:HelloDeveloper 很多人说,看了再多的文章,可是没有人手把手地教授,还是很难真正地入门AI。为了将AI知识体系以最简单的方式呈现给你,从这个星期开始,芯君邀请AI专业人士开设“...

百度开发者中心
2019/09/23
8
0
在Ruby on Rails中对nil v。空v。空白的简要解释 - A concise explanation of nil v. empty v. blank in Ruby on Rails

问题: I find myself repeatedly looking for a clear definition of the differences of nil? 我发现自己一再寻找nil?差异的明确定义nil? , blank? , blank? , and empty? , empty? in ......

javail
40分钟前
15
0
DevOps与NoOps现状分析

时下的IT趋势中,DevOps 正是一个热语。它起源于几年前SPA (单页面应用) 的前端应用.我认为常态的IT技术适应就是,在新技术爆发的那一时刻开始,立马就会被敏锐的人们所采用,然后被快速传播...

tidings_
43分钟前
17
0
OSChina 周六乱弹 —— 代码创造人工生命

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @小小编辑推荐:《inner universe》 - ORIGA 《inner universe》 - ORIGA 手机党少年们想听歌,请使劲儿戳(这里) 当机器人具有意识的时候,...

小小编辑
今天
16
1
怎么创建远程桌面连接

1、IIS7远程桌面 管理中文最新版是一款专业的远程桌面管理工具,更新了原09网络远程桌面管理,较之以前的版本,操作更加便捷,能够同时远程多台服务器,多台服务器间自由切换,完全无压力。I...

吹的心痒痒
今天
22
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部