django复习 以及源码
django请求生命周期
在浏览器上输入网址会发生什么事?
(地址会朝我对应的ip地址发送get请求,get请求遵循http协议)
先进入实现了wsgi协议的web服务器----》进入django---》中间件---》路由---》视图---》取模板,取数据,用数据渲染模板---》返回模板的字符串---》在浏览器上看到页面了
1 wsgi和cgi:通用网关协议
# 实现了wsgi协议的web服务器:uwsgi
# 对应到java中就是tomcat
最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。
from wsgiref.simple_server import make_server def mya(environ, start_response):
print(environ)
start_response('200 OK', [('Content-Type', 'text/html')])
if environ.get('PATH_INFO') == '/index':
with open('index.html','rb') as f:
data=f.read() elif environ.get('PATH_INFO') == '/login':
with open('login.html', 'rb') as f:
data = f.read()
else:
data=b'<h1>Hello, web!</h1>'
return [data] if __name__ == '__main__':
myserver = make_server('', 8011, mya)
print('监听8010')
myserver.serve_forever()
整个django框架就相当于def mya这个函数,只不过diango不是用函数,是用类包装起来。
对象加()调用是__call__的方法,__call__里面有这两个参数(environ, start_response),只要遵循这个http协议就会有这两个参数。wsgi就是将http请求拆开了,拆成python当中能够识别的变量,http直接来,能读出来就是字符串,但是还要做相应的处理,所以协议规定按照什么格式拆,拆到哪里,就是将数据当成字典拆到environ里面去,不管请求方式,请求头部等等然后再传到后面的可调用对象里面去,然后django就把这个东西包装成了对象request,所以request可以点http里的数据点出来。
开发模式

# 开发模式(前后端分离和前后端不分离)
# -前后端不分离项目(后端渲染页面)
# -前后端分离项目
# -前端和后端通过json格式数据交互(不需要写模板语言)请求页面用ajax发请求,前后端只做json数据的交互,json数据拿回来的时候就用dom来渲染我的页面,前端拿到数据,页面前端自己渲染
前端可以是前端,后台,移动端和微信小程序
https://www.cnblogs.com/liuqingzheng/p/10900502.html
cbv源码分析
-FBV和CBV
# -执行流程:
# -路由如果这么配置:url(r'^test/', views.Test.as_view()),
# 请求通过中间件后进入路由--->根据路由匹配,一旦成功,会执行后面函数(request)---》本质就是执行了as_view内部的view函数----》内部又调用了self.dispatch---->根据请求方式,执行不同的方法(必然get请求,就会执行咱么写的视图类的get方法)
# -尝试自己封装一个APIView,重写dispatch方法,在执行父类的dispatch之前,写一些逻辑,请求来了,就会执行这些逻辑
url()其实就是一个函数,views.Test.as_view()就是函数地址加括号,并且把request传进去,
# python中一切皆对象
# def test():
# print('xxxx')
# test.name='lqz'
# print(test.name)
restful规范(importment,interview)
一 什么是RESTful
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
- 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)
- 资源就是实实存在的东西,如从动物园中新增一头动物,杀死一头动物 -10条
# -1 API与用户的通信协议,总是使用HTTPs协议。(http不安全,数据被截断,数据就会全部展示出来)
# -2 域名有区分
(dtl是模板语言,可以使用python等进行模板渲染再返回给前端)
(后台管理并没有做前后端分离,用的就是dtl,而不是前端渲染)
# -https://api.example.com 尽量将API部署在专用域名(会存在跨域问题)
# -https://example.org/api/ 访问api代表就是访问路由接口
# -3 版本
(就是如微博开一个接口,然后我写一个app去访问这个接口,需要传入两个参数,返回一个参数,然后后期微博数据需要改动,
变成了一个接口需要传入三个参数,返回两个参数,不可能去改变我的app,只能再更新一个微博版本,开一个新的接口,
然后app去连接一个新的接口,这期间就会有缓冲的过程)
# -可以放在路径中 URL 如:https://api.example.com/v1/
# -可以放在请求头中 跨域时,引发发送多次请求
# -4 路径,视网络上任何东西都是资源,均使用名词表示(重点)
# -https://api.example.com/v1/zoos
# -5 通过method 区分是什么操作
# -get表示获取
# -post表示新增
# -delete表示删除
# -patch/put 表示修改
# -6 过滤,通过在url上传参的形式传递搜索条件
- https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
- https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
- https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
- https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
- https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
# -7 状态码
# {"status_code":100}
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
# -8 错误处理,应返回错误信息
# {"status_code":100,'msg':'登录成功'}
# {"status_code":101,'msg':'用户名错误'}
# -9 返回结果,针对不同操作,服务器向用户返回的结果
# -get获取所有资源/get获取一个资源
# -127.0.0.1/api/vi/books 获取所有图书
# {"status_code":100,'msg':'获取成功',data:[{},{}]}
# -127.0.0.1/api/vi/books/3 获取id为3的图书
# {"status_code":100,'msg':'获取成功',data:{name:xx,....}}
# -新增数据,把新增的数据再返回
# -修改了数据,返回完整的资源对象
# -删除数据,返回一个空文档
- 错误处理,应返回错误信息,error当做key。
123
{error:"Invalid API key"} - 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
123456
GET/collection:返回资源对象的列表(数组)GET/collection/resource:返回单个资源对象POST/collection:返回新生成的资源对象PUT/collection/resource:返回完整的资源对象PATCH/collection/resource:返回完整的资源对象DELETE/collection/resource:返回一个空文档
#
# -10 返回结果中提供链接
Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
|
1
2
3
4
5
6
|
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json"}} |
django编写restful接口
# DG软件
# -pycharm开发
# -idea
# -goland
# -AndroidStadio
不同程序可以用同一个数据库
views.py
from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
from app01 import models
def Book(request):
#获取所有的图书
if request.method == 'GET':
books = models.Book.objects.all()
#把queryset对象转成json格式的字符串
# li = []
# for book in books:
# bo = {'name':book.name,'publish':book.publish}
# li.append(bo)
#列表推导式
li=[{'name':book.name,'publish':book.publish} for book in books ] response = {'code':100,'msg':'查询成功','data':li}
#safe=False 如果序列化的对象中有列表,需要设置
return JsonResponse(response ,safe=False,json_dumps_params={'ensure_ascii':False})
models.py
from django.db import models # Create your models here. class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super(JsonResponse, self).__init__(content=data, **kwargs)
源码
APIView源码简单分析
# 6 drf:APIView 的源码,Requset的源码
# -安装:
# -pip3 install djangorestframework
# -pycharm中安装
# -使用
# -第一步,再写视图,都写cbv
# from rest_framework.views import APIView
# class Books(APIView):
# pass
# -在setting中配置
# INSTALLED_APPS= [
# 。。。。。
# 'rest_framework'
# ]
#
# -源码分析:
# 继承了APIView 之后:
# -1 所有的请求都没有csrf的认证了
# -2 在APIView中as_view本质还是调用了父类的as_view(View的as_view)
# -3 as_view中调用dispatch -----》这个dispatch是APIView的dispatch
@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function. This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation view = super(APIView, cls).as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs # Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
源码
def csrf_exempt(view_func):
"""
Marks a view function as being exempt from the CSRF view protection.
"""
# We could just do view_func.csrf_exempt = True, but decorators
# are nicer if they don't have side-effects, so we return a new
# function.
def wrapped_view(*args, **kwargs):
return view_func(*args, **kwargs)
wrapped_view.csrf_exempt = True
return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)
源码
class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
""" http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def __init__(self, **kwargs):
"""
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in six.iteritems(kwargs):
setattr(self, key, value) @classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
源码
APIView的dispatch方法和request类分析
-APIVIew的dispatch方法:
# -1 对原生request对象做了一层包装(面向对象的封装),以后再用的request对象都新的request对象
# -2 在APIView中self.initial(request, *args, **kwargs),里面有频率控制,权限控制和认证相关
# -3 根据请求方法执行咱们写的视图类中的相应方法
# --视图类中方法的request对象,已经变成了封装后的request
# -Request类:
# -1 原生的request是self._request
# -2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式)
# -3 query_params 就是原生request的GET的数据
# -4 上传的文件是从FILES中取
# -5 (重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)
postman的安装和使用
美化jason的格式


-Django的请求生命周期
-CBV源码分析
-类名.as_view()---->执行结果返回内存地址---》内存函数view的内存地址---》请求路径跟路由匹配成,会调用view(request)
view()内部调用了self.disaptch---->根据请求不同,执行不同的方法 -restful规范:
-10
-1 路径中资源都名词,可以用复数
-2 通过请求方式来执行不同操作
-3 返回状态码
-4 返回错误信息
-5 返回的数据中带链接
-用原生django写restful的接口
-drf
-使用:
-1 在setting.py 中把rest_framework加入到app中
-2 以后再写全写CBV,继承APIView
-源码分析:
-APIView:重写了dispatch方法:1 包装request 2 加入了一些校验
-Request对象:重写了__getattr__ query_params FILES request.data
图书的增删查改接口
# -登录之后才能操作修改,新增,删除接口
from django.db import models # Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField()
# 阅读数
# reat_num=models.IntegerField(default=0)
# 评论数
# commit_num=models.IntegerField(default=0) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE) class AuthorDatail(models.Model):
nid = models.AutoField(primary_key=True)
telephone = models.BigIntegerField()
birthday = models.DateField()
addr = models.CharField(max_length=64) class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
models.py
from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
class Meta:
model=models.Book
fields='__all__'
# depth=1
myserializer.py
from django.shortcuts import render # Create your views here.
class Get():
def get(self,request,*args,**kwargs):
response = {'code': 100, 'msg': '查询成功'}
ret=self.models_object
book_ser=self.ser(instance=ret,many=True)
response['data']=book_ser.data
return Response(response) from app01 import models
from app01.MySer import BookSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
class Books(APIView,Get):
models_object=models.Book.objects.all()
ser=BookSerializer def post(self,request,*args,**kwargs):
print(request.data)
print(type(request.data))
response={'code': 100, 'msg': '新增成功'}
book_ser=BookSerializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
else:
response['code']=101
response['msg']=book_ser.errors return Response(response) class BookDetail(APIView):
def get(self,request,id):
response = {'code': 100, 'msg': '查询成功'}
ret=models.Book.objects.filter(pk=id).first()
book_ser=BookSerializer(instance=ret,many=False)
response['data']=book_ser.data
return Response(response)
def put(self,request,id):
response = {'code': 100, 'msg': '修改成功'}
ret=models.Book.objects.filter(pk=id).first()
book_ser=BookSerializer(instance=ret,data=request.data)
if book_ser.is_valid():
book_ser.save()
else:
response['code'] = 101
response['msg'] = book_ser.errors
return Response(response) def delete(self, request, id):
response = {'code': 100, 'msg': '删除成功'}
models.Book.objects.filter(pk=id).delete() return Response(response) class Publish(APIView,Get):
models_object=models.Publish.objects.all()
ser=BookSerializer
views.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^books/$', views.Books.as_view()),
url(r'^books/(?P<id>\d+)$', views.BookDetail.as_view()), ]
urls.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'rest_framework'
]
settings.py
301和302的区别
302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。
而301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址
定义如下:
301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302 Found 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
字面上的区别就是301是永久重定向,而302是临时重定向。 当然,他们之间也是有共同点的,就是用户都可以看到url替换为了一个新的,然后发出请求。
301适合永久重定向
301比较常用的场景是使用域名跳转。
比如,我们访问 http://www.baidu.com 会跳转到 https://www.baidu.com,发送请求之后,就会返回301状态码,然后返回一个location,提示新的地址,浏览器就会拿着这个新的地址去访问。
注意: 301请求是可以缓存的, 即通过看status code,可以发现后面写着from cache。
或者你把你的网页的名称从php修改为了html,这个过程中,也会发生永久重定向。
302用来做临时跳转
比如未登陆的用户访问用户中心重定向到登录页面。
访问404页面会重新定向到首页。
##niginx 301/302配置
rewrite后面接上permenent就代表301跳
//把来自veryyoung.me的请求301跳到 www.veryyoung.me
if ($host != 'veryyoung.me') {
rewrite ^/(.*)$ http://www.veryyoung.me/$1 permanent;
}
接上redirect就代表302跳
//把来自veryyoung.me的请求302跳到 www.veryyoung.me
if ($host != 'veryyoung.me') {
rewrite ^/(.*)$ http://www.veryyoung.me/$1 redirect;
}
跨域
一、为什么会出现跨域问题
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
二、什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 否 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)
三、非同源限制
【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
【2】无法接触非同源网页的 DOM
【3】无法向非同源地址发送 AJAX 请求
四、跨域解决方法
【1】设置document.domain解决无法读取非同源网页的 Cookie问题
因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie
// 两个页面都设置
document.domain = 'test.com';
【2】跨文档通信 API:window.postMessage()
调用postMessage方法实现父窗口http://test1.com向子窗口http://test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)
// 父窗口打开一个子窗口
var openWindow = window.open('http://test2.com', 'title'); // 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', 'http://test2.com');
调用message事件,监听对方发送的消息
// 监听 message 消息
window.addEventListener('message', function (e) {
console.log(e.source); // e.source 发送消息的窗口
console.log(e.origin); // e.origin 消息发向的网址
console.log(e.data); // e.data 发送的消息
},false);
【3】JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字 // 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(data){
//处理获得的数据
}
</script>
【4】CORS
CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
1.前端代码(需要判断浏览器是否支持情况)
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// 此时即支持CORS的情况
// 检查XMLHttpRequest对象是否有“withCredentials”属性
// “withCredentials”仅存在于XMLHTTPRequest2对象里
xhr.open(method, url, true);
} else if (typeof!= "undefined") {
// 否则检查是否支持XDomainRequest,IE8和IE9支持
// XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// 否则,浏览器不支持CORS
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
}
2.服务器
服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。我们主要介绍Apache和PHP里的设置方法
Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可
Header set Access-Control-Allow-Origin *
PHP使用如下代码设置即可
<?php
header("Access-Control-Allow-Origin:*")
django复习 以及源码的更多相关文章
- Django搭建及源码分析(三)---+uWSGI+nginx
每个框架或者应用都是为了解决某些问题才出现旦生的,没有一个事物是可以解决所有问题的.如果觉得某个框架或者应用使用很不方便,那么很有可能就是你没有将其使用到正确的地方,没有按开发者的设计初衷来使用它,当 ...
- Django Rest Framework源码剖析(八)-----视图与路由
一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...
- Django Rest Framework源码剖析(三)-----频率控制
一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过 ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- Django如何启动源码分析
Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- 跨站请求伪造(csrf),django的settings源码剖析,django的auth模块
目录 一.跨站请求伪造(csrf) 1. 什么是csrf 2. 钓鱼网站原理 3. 如何解决csrf (1)思路: (2)实现方法 (3)实现的具体代码 3. csrf相关的装饰器 (1)csrf_p ...
- Django rest framework源码分析(一) 认证
一.基础 最近正好有机会去写一些可视化的东西,就想着前后端分离,想使用django rest framework写一些,顺便复习一下django rest framework的知识,只是顺便哦,好吧. ...
- Django搭建及源码分析(二)
上节针对linux最小系统,如何安装Django,以及配置简单的Django环境进行了说明. 本节从由Django生成的manage.py开始,分析Django源码.python版本2.6,Djang ...
随机推荐
- 支持向量机 SVM - Wenjing
概念 将向量映射到一个更高维的空间里,在这个空间里建立有一个最大间隔超平面.在分开数据的超平面的两边建有两个互相平行的超平面,分隔超平面使两个平行超平面的距离最大化.假定平行超平面间的距离或差距越大, ...
- 从846家初创倒下 看A轮融资后的悬崖
看A轮融资后的悬崖" title="从846家初创倒下 看A轮融资后的悬崖"> 相比往年,今年的寒冷冬天来得更早.在互联网行业,今年的"大雪"更 ...
- 初学Qt——tableview操作
先做简短记录改天有空再详细讲一些吧 使用QSqlQueryModel绑定了TableView,因为需要用到数据表中Id这一项,但又不想显示出来,找到方法是 在绑定之后对tableView 调用setC ...
- UBB代码
UBB代码是HTML(标准通用标记语言下的一个应用)的一个变种,是Ultimate Bulletin Board (国外的一个BBS程序)采用的一种特殊的TAG.您也许已经对它很熟悉了.UBB代码很简 ...
- jsvascript篮球梦
首先让我们先欣赏一下效果图: html文本: <div class="box"> <img id="imgshow" src="la ...
- display的block、none、inline属性及解释
常会用到display对应值有block.none.inline这三个值 参数: block :块对象的默认值.用该值为对象之后添加新行.之前也添加一行. none :隐藏对象.与visibility ...
- ubuntu下安装typescript
安装ts之前需要安装好node, 安装ts: 1. npm install -g typescript /opt/node/bin/tsc -> /opt/node/lib/node_modul ...
- sf-git机制
为什么要专门写一篇关于sf科技公司的GIT管理机制呢?因为本周经历了两天的学习和考试,刚开始没在意,因为之前公司也用的GIT,所以没怎么看视频,就看了文档,练习考试时候才发现并非以前的那种git流程, ...
- vue环境搭建过程中,npm权限不足问题
今天在用git bash进行全局安装vue-cli的时候,报错: 必须以管理员权限进行安装才行.所以用cmd命令工具,点击右键命令提示符cmd--------以管理员身份运行--------cd进入到 ...
- PHP8年开发经验原创开发文档教程
订阅微信公众号: gzgwgas 每天为你分享PHP开发经验,坚决不踩坑,坚决不入坑. 微信扫码,关注公众号有惊喜!