Javascript CORS与jQuery Dropzone一起出现问题并上传到Imgur

Javascript CORS与jQuery Dropzone一起出现问题并上传到Imgur,javascript,cors,dropzone.js,imgur,Javascript,Cors,Dropzone.js,Imgur,我尝试使用jQuery Dropzone将图像上载到Imgur或任何其他域,但这不起作用 这是我的dropzone设置: $("div.dropzone").dropzone success: -> console.log arguments paramName: "image" method: "post" maxFilesize: 2 url: "https://api.imgur.com/3/upload" headers: Authorization

我尝试使用jQuery Dropzone将图像上载到Imgur或任何其他域,但这不起作用

这是我的dropzone设置:

$("div.dropzone").dropzone
  success: -> console.log arguments
  paramName: "image"
  method: "post"
  maxFilesize: 2
  url: "https://api.imgur.com/3/upload"
  headers:
    Authorization: "Client-ID *************"
这不管用。它表示返回代码为0。请求标题:

Host: api.imgur.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Origin: http://my.opencubes.io
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,cache-control,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
首先,您可以看到cient id没有出现:(。但最大的问题是所使用的方法是
选项。
。响应标题:

当我尝试将文件上载到我的另一个域(dropzone位于子域中)时,我遇到了相同的问题。

在控制台中,我看到:

Une demande multi-origines (Cross-Origin Request) a été bloquée : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur https://api.imgur.com/3/upload. Ceci peut être corrigé en déplaçant la ressource sur le même domaine ou en activant CORS.
可以翻译成

阻止了多来源请求:策略“同一来源”不允许查看位于中的远程资源。可以通过移动samin域上的资源或启用CORS来修复此问题


您正在运行浏览器的。每个浏览器都有一个;“源代码”基本上意味着“同一个站点”。我在example.com上的JavaScript可以在example.com上访问它喜欢的任何内容,但它不允许从display.com、example.net或api.example.com读取任何内容。它们来自不同的源代码

没有它,我可以写一个网页,窃取你所有的gmail和私人Facebook照片。我的恶意JavaScript会向gmail.com和Facebook.com发出网络请求,找到你的电子邮件和照片的链接,也加载这些数据,然后将其发送到我自己的服务器

但有些服务(如API)是为其他服务访问而设计的。这就是跨源资源共享的原因。Web服务可以使用CORS告诉浏览器允许从脚本访问是可以的。如果您想通过提交到自己的服务器来测试代码,请确保您的服务器是可用的

如果您在本地开发,还必须确保从web服务器进行测试—一个以
http://
开头的地址,而不是
file://
。该协议是源代码的一部分,因此您不能从文件URL提交到http端点


CORS具有不同类型的请求。有些请求被视为简单请求,但其他请求(具有自定义标头的请求)则被视为需要“”。这意味着浏览器将向服务器发送一个请求,说明“此请求是否适用于CORS?”在发送实际请求之前使用HTTP
OPTIONS
方法。任何具有自定义标题的请求都需要预处理;这就是您的HTTP
OPTIONS
的来源。jQuery,因此即使您没有添加这些,您仍然会在实际发布之前看到该
OPTIONS
请求

从您的屏幕截图来看,Imgur似乎将允许您的HTTP
POST
方法。让我们继续了解为什么这不起作用


我们正在使用。这有一个必需的参数(
image
),如果我们只需要匿名上传,我们需要的就是。上传方法允许我们向图像发送一个简单的URL以进行上传,因此让我们尝试向Imgur发出AJAX请求:

$.ajax
  success: (data) -> console.log data
  type: "POST"
  data: 
    image: "http://placehold.it/300x500"
  url: "https://api.imgur.com/3/upload"
  headers:
    Authorization: "Client-ID *************" # Don't forget to put your actual Client-ID here!
下一步是尝试使用从表单读取文件并发送该文件。下面是一个CoffeeScript提交处理程序:

$('#file-form').submit (ev) -> 
  ev.preventDefault()
  file = $('#file-form input[name=file]').get(0).files[0] 
  $.ajax
    success: (data) -> console.log data
    type: "POST"
    data: 
      image: file
    url: "https://api.imgur.com/3/upload"
    headers:
      Authorization: "Client-ID *************"
最后,我们可以尝试使用来实现相同的目标:

$("div.dropzone").dropzone
  success: (file, response) -> 
    console.log file
    console.log response
  paramName: "image"
  method: "post"
  maxFilesize: 2
  url: "https://api.imgur.com/3/upload"
  headers:
    "Authorization": "Client-ID *************"
Dropzone
success
回调函数获取两个参数:上载的文件和服务器的响应。您可能对后者最感兴趣;您可以使用后者向用户显示其新上载的图像



有一个使用JavaScript中的Imgur API的示例项目。

选项请求是一个普通请求:用于请求与CORS限制相关的权限。了解CORS如何在引擎盖下工作

在您的情况下,这是一个纯CORS相关问题。选项请求包含以下标题:

Access-Control-Request-Headers: authorization,cache-control,x-requested-with
这意味着:我可以在跨域AJAX请求中使用“authorization”、“cache control”和“x-requested-with”头吗

您得到的答复如下:

Access-Control-Allow-Headers :"Authorization, Content-Type, Accept, X-Mashape-Authorization"
这意味着:只允许使用这些标题:“授权”、“内容类型”、“接受”和“X-Mashape-Authorization”

如您所见,“缓存控制”和“x-requested-with”未列在允许列表中,导致浏览器拒绝请求

我有两个测试代码示例显示了这种行为:

例1(工作) 以下是运行此代码时发送的飞行前请求的标题(如Firefox 30 devtools所示,我已删除了不相关的标题,如User Agent、Accept…):

  • 选项
  • 主持人:api.imgur.com
  • 来源:
  • 访问控制请求方法:POST
  • 访问控制请求头:授权
  • 缓存控制:没有缓存
以及相应响应的标题

  • 访问控制允许来源:“*”
  • 访问控制允许方法:“获取、放置、发布、删除、选项”
  • 访问控制允许标题:“授权,内容类型,接受,X-Mashape-Authorization”
在这里,我们可以看到,我们提示访问“authorization”头,服务器接受这个头,并使用POST方法和任何源URL进行分配,因此满足了CORS要求,并且浏览器允许该请求

示例2(不工作) 飞行前请求的标题:

  • 选择权
  • 主持人:api.imgur.com
  • 来源:
  • 访问控制请求方法:POST
  • 访问控制请求头:授权,缓存控制
  • 缓存控制:没有缓存
飞行前响应的标题(与示例1相同):

  • 访问控制允许来源:“*”
  • 访问控制允许方法:“获取、放置、发布、删除、选项”
  • 访问控制允许标题:“授权、内容类型、接受、X-Mashape-Authorization”
这里是“访问控制请求”
var data = new FormData();
data.append('image', 'http://placehold.it/300x500');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.imgur.com/3/upload', true);
xhr.setRequestHeader('Authorization', 'Client-ID xxxxxxxxxx');
xhr.send(data);
var data = new FormData();
data.append('image', 'http://placehold.it/300x500');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.imgur.com/3/upload', true);
xhr.setRequestHeader('Authorization', 'Client-ID xxxxxxxxxx');
// the only difference with the previous code is this line
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.send(data);
var myDropzone = new Dropzone('.dropzone', {
    //...
    headers: {
        'Authorization': authorizationHeader,
        // remove Cache-Control and X-Requested-With
        // to be sent along with the request
        'Cache-Control': null,
        'X-Requested-With': null
    }
});
var myDropzone = new Dropzone('.dropzone', {
    //...
    headers: {
        'Authorization': authorizationHeader,
        // remove Cache-Control and X-Requested-With
        // to be sent along with the request
    }
});