处理跨域请求

<div class="iteye-blog-content-contain" style="font-size: 14px"><p>&lt;div id="cnblogs_post_body"&gt;</p>
<p>&nbsp;&lt;p&gt;浏览器具有同源策略,会禁止向与当前页面不同的域发送请求,只要是协议,域名,端口中有任何一个不同,都被当作是不同的域,这虽然是一种保护数据的机制,但是对我们开发来说确是个麻烦,解决办法有很多,这里介绍一下JSONP和CORS&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;先来理解一下浏览器这个同源策略是什么,就是浏览器禁止掉&lt;strong&gt;向其他域名&lt;/strong&gt;发送的请求,其实是在&lt;strong&gt;请求回来&lt;/strong&gt;的时候被禁掉的&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;img src="http://images2017.cnblogs.com/blog/1164899/201711/1164899-20171120163200633-931000397.png" alt="" /&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;哪些操作会受同源策略,哪些不会呢?&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;  &lt;strong&gt;requests模块&lt;/strong&gt;不受影响,因为没有经过浏览器&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;  &lt;strong&gt;ajax发请求时,浏览器会限制&lt;/strong&gt;(我们就是要解决这个问题)&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;  有&lt;strong&gt;src属性&lt;/strong&gt;的都不受同源策略限制  &amp;nbsp;-img,script,iframe&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;    但是注意,script中的src,拿到的数据会当作&lt;strong&gt;js代码&lt;/strong&gt;执行,所以不能直接把数据放到src中&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;span style="font-size: 18px"&gt;&lt;strong&gt;JSONP&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;  &lt;/strong&gt;jsonp是一种机智的方式,本质就是在远程发送数据的时候,在数据外层套一个函数名,&lt;strong&gt;把数据以函数的形式返回&lt;/strong&gt;(&lt;strong&gt;这样才能被script识别&lt;/strong&gt;)&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;  在&lt;strong&gt;本地先定义一个函数&lt;/strong&gt;,当远程发送过来数据,本地就&lt;strong&gt;当成一个函数执行&lt;/strong&gt;,&lt;strong&gt;真实数据就相当于参数&lt;/strong&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;  &lt;/strong&gt;jsonp本质就是创建一个script标签,把url放到src属性中,就是相当于发送了一个get请求,事实上jsonp只能发送get请求&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;用一个简单的示例来理解一下jsonp的本质&lt;/strong&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;客户端的地址是:localhost:8000,要向服务端&amp;nbsp;localhost:8888&amp;nbsp;发送请求,获取数据,&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;利用jsonp来避开同源策略:&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;客户端:&lt;/strong&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #ff00ff"&gt;DOCTYPE html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html &lt;/span&gt;&lt;span style="color: #ff0000"&gt;lang&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;charset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;http-equiv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;x-ua-compatible&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;IE=edge&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;viewport&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;width=device-width, initial-scale=1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Title&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;button &lt;/span&gt;&lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;jsonp('http://127.0.0.1:8888/get_data?callback=func')&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;获取数据&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;{#通过参数向服务端发送函数名,这样就能实现动态生成函数名#}&lt;/pre&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="background-color: #f5f5f5; color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; func(arg) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; console.log(arg);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; document.head.removeChild(tag);</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; jsonp(url) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; tag &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; document.createElement(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;script&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;);&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000"&gt;创建一个script标签,用来发送请求,注意是一个全局的变量,以便在func函数中删除&lt;/span&gt;</p>
<p>&lt;span style="background-color: #f5f5f5; color: #000000"&gt;&nbsp; &nbsp; &nbsp; &nbsp; tag.src &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; url;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; document.head.appendChild(tag); &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000"&gt;在html的头文件中添加这个script标签&lt;/span&gt;</p>
<p>&lt;span style="background-color: #f5f5f5; color: #000000"&gt;&nbsp; &nbsp; }</p>
<p>&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;服务端:&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;from djan&lt;a href="http://www.cppentry.com/list.php?fid=78"&gt;GO&lt;/a&gt;.shortcuts import HttpResponse&lt;br /&gt;&lt;br /&gt;def get_data(request):&lt;br /&gt;&nbsp; &nbsp; func_name = request.GET.get('callback')#从请求头中获取函数名&lt;br /&gt;&nbsp; &nbsp; return HttpResponse('%s(数据)'%func_name)#返回一个函数,把数据当作参数&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;1.jsonp就是利用script的src发送请求不会被受同源策略限制,然后通过src属性向服务端发送请求&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;2.script会把请求来的数据当成是js代码,所以服务端返回的数据不能直接是数据,会报错&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;3.把返回值封装成一个函数的形式,真实数据放在函数的参数中,客户端等收到后,从函数中拿到数据就行了&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;4.这个函数名最好是动态生成的,不然每次发送一个请求就要前后端商量好函数名,太麻烦&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;以上就是jsonp的原理&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;所以使用jsonp,本地需要定义一个函数,而远程需要把数据封装成一个函数&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;再来看看ajax如何实现跨域请求&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #ff00ff"&gt;DOCTYPE html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html &lt;/span&gt;&lt;span style="color: #ff0000"&gt;lang&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;charset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;http-equiv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;x-ua-compatible&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;IE=edge&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;viewport&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;width=device-width, initial-scale=1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Title&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;button &lt;/span&gt;&lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;jsonp()&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;获取数据&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="background-color: #f5f5f5; color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; func(arg) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; console.log(arg);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; document.head.removeChild(tag);</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; {# &lt;strong&gt;这种实际上就是内部帮我们实现创建一个script标签&lt;/strong&gt;#}</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt; jsonp() {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; $.ajax({</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url:&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;http://127.0.0.1/get_data&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type:&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;GET&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType:&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;JSONP&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsonp:&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;callback&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsonCallback:&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;func&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;{# &lt;strong&gt;这两行就是自动在url后面添加&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;?&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;callback&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;=&lt;/span&gt;&lt;/strong&gt;&lt;span style="background-color: #f5f5f5; color: #000000"&gt;&lt;strong&gt;func&lt;/strong&gt; #}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; }</p>
<p>&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;jsonp只能发送get请求,但是可不是所有的数据都能封装在参数中,想要发送post请求,还得用CORS&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;hr /&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;span style="font-size: 18px"&gt;&lt;strong&gt;CORS跨站资源共享(Cross-Origin Resource Sharing)&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;再来看一下跨域请求时,浏览器的提示信息:&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;img src="http://images2017.cnblogs.com/blog/1164899/201711/1164899-20171120163200633-931000397.png" alt="" /&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;之所以ajax发送请求,返回的数据拿不到,是因为少了一点东西。提示缺少一个响应头,所以CORS的原理就是添加上这个响应头&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;只需要修改视图函数&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;from&lt;/span&gt; djan&lt;a href="http://www.cppentry.com/list.php?fid=78"&gt;GO&lt;/a&gt;.shortcuts &lt;span style="color: #0000ff"&gt;import&lt;/span&gt;&lt;span style="color: #000000"&gt; HttpResponse</p>
<p>&nbsp;</p>
<p>&lt;/span&gt;&lt;span style="color: #0000ff"&gt;def&lt;/span&gt;&lt;span style="color: #000000"&gt; get_data(request):</p>
<p>&nbsp; &nbsp; response &lt;/span&gt;= HttpResponse(&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;数据&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)</p>
<p>&nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;http://127.0.0.1:8888&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;这样表示允许这个地址访问&lt;/span&gt;</p>
<p>&nbsp; &nbsp; #response[&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;*&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;这样表示允许所有地址访问&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; response&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;这样就可以了,这是最简单的情况,本地不用做任何事,远程设置一个响应头&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;还有一种复杂点的情况:&lt;strong&gt;非简单请求&lt;/strong&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;简单请求&amp;amp;非简单请求:&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;  简单请求的条件:  &lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;    1.请求方式为&amp;nbsp;HEAD,GET,POST&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;    2.请求头中Content-Type的值是下面这三个中的一个&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;      application/x-www-form-urlencoded&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;      multipart/form-data&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;      text/plain&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;    &lt;strong&gt;同时满足以上两个条件时,才是简单请求,有一个不满足就是复杂请求&lt;/strong&gt;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;对于复杂请求,以PUT请求为例,会先发一个&lt;strong&gt;options请求&lt;/strong&gt;,用来预检,对于预检请求,也要返回响应头&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;远程视图函数要这样处理:&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;def&lt;/span&gt;&lt;span style="color: #000000"&gt; data(request):</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; request.method == &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;OPTIONS&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;预检&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response =&lt;span style="color: #000000"&gt; HttpResponse()</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;*&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Methods&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;PUT&lt;/span&gt;&lt;span style="color: #800000"&gt;'#允许这个请求头  &lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; response</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;elif&lt;/span&gt; request.method == &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;PUT&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;预检通过后真正的请求&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response = HttpResponse(&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;数据&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;*&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; response&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;&lt;strong&gt;如果GET请求自定义请求头,也变成了复杂请求&lt;/strong&gt;,也需要设置一下,允许这个请求头&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;比如自定义了一个请求头:xxx:yyyy&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;p&gt;那远程代码中就要允许这个请求头&lt;/p&gt;&nbsp;</p>
<p>&nbsp;&lt;div class="cnblogs_code"&gt;&nbsp;</p>
<p>&nbsp; &lt;pre&gt;&lt;span style="color: #0000ff"&gt;def&lt;/span&gt;&lt;span style="color: #000000"&gt; data(request):</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; request.method == &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;OPTIONS&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;预检&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response =&lt;span style="color: #000000"&gt; HttpResponse()</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;*&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; response['Access-Control-Allow-Methods'] = 'PUT'&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Headers&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;xxx&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;允许这个请求头&lt;/span&gt;</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; response</p>
<p>&nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;elif&lt;/span&gt; request.method == &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;PUT&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;预检通过后真正的请求&lt;/span&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response = HttpResponse(&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;数据&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; response[&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;] = &lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;*&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; response&lt;/pre&gt;&nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; 虽然复杂请求可以解决</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; 但是,要尽量避免复杂请求,会增加服务器压力</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; &lt;hr /&gt;总结,解决跨域请求,常用的有三种方式:requests模块,cors,jsonp</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; 后两种直接从前端拿数据,不需要经过服务器,requests模块是先把请求发送到服务器,服务器向目标发送请求,再返回数据到本地</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; &amp;nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; jsonp和cors相比,兼容性更好一点</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; &amp;nbsp;</p>
<p>&nbsp;&lt;/div&gt;&nbsp;</p>
<p>&nbsp;&lt;div&gt;</p>
<p>&nbsp; 参考博客:http://www.cnblogs.com/wupeiqi/articles/5703697.html</p>
<p>&nbsp;&lt;/div&gt;</p>
<p>&lt;/div&gt;</p></div>

猜你喜欢

转载自ymssl.iteye.com/blog/2406733