没有jQuery的Cloudinary客户端直接上传
Cloudinary client-side direct upload without jQuery
我在没有 jQuery 的情况下使用 Cloudinary,并尝试通过浏览器直接上传。
我已按照说明 HERE 创建了一个名为 seller
的上传预设。
问题是,当我从客户端发帖时(使用 Angular),我得到回复:
XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/mycloud/image/upload. Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.
据我所知,这是一个 CORS 问题。我正在提出请求,如下所示。
req =
method: 'POST'
url: 'https://api.cloudinary.com/v1_1/mycloud/image/upload'
headers:
'Access-Control-Allow-Credentials': 'true'
file: scope.file
data:
upload_preset: 'seller'
$http(req)
.success (data, status, headers, config) ->
console.log 'file is uploaded successfully. Response: ' + data
.error (err) ->
console.log 'file error', err
我错过了什么?没有他们的 jQuery 插件就无法直接上传 Cloudinary 吗?
要解决许多 CORS 相关问题和浏览器不兼容问题,您最好使用来自 jquery.cloudinary.js 或 ng-file-upload 的基于 jQuery 的上传器。您可以在此处查看这两个示例 - https://github.com/cloudinary/cloudinary_angular/tree/master/samples/photo_album
特别是,CORS 请求因您传递的 Access-Control-Allow-Credentials header 而被拒绝。请尝试将其删除。
这是一个使用 AngularJS 1.3 的工作解决方案,可以在没有 jQuery 插件的情况下在 cloudinary 上执行直接未签名的上传:
var file = /* your file */;
var cloud_name = 'your cloud_name';
var fd = new FormData();
fd.append('upload_preset', 'seller');
fd.append('file', file);
$http
.post('https://api.cloudinary.com/v1_1/' + cloud_name + '/image/upload', fd, {
headers: {
'Content-Type': undefined,
'X-Requested-With': 'XMLHttpRequest'
}
})
.success(function (cloudinaryResponse) {
// do stuff with cloudinary response
// cloudinaryResponse = { public_id: ..., etc. }
})
.error(function (reponse) {
});
如果有人正在寻找 Angular ng-flow + cloudinary 解决方案,我在这里创建了一个基本设置
按照本教程进行简单的解决,效果很好..
http://prasanthco.de/tutorials/cloudinary-image-upload-using-angularjs/
这样做。
Index.html - 以相同顺序包含文件..
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.1/lodash.min.js"></script>
<script src="https://github.com/cloudinary/pkg-cloudinary-core/blob/master/cloudinary-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular.min.js"></script>
<script src="https://github.com/cloudinary/cloudinary_angular/blob/master/js/angular.cloudinary.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload.min.js"></script>
app.js - 注入模块
var app = angular.module('myApp', [
'cloudinary',
'ngFileUpload'
]);
home.html - 您需要图片上传选项的任何视图
<div class="container" ng-hide="loader">
<div class="deal">
<label class="black bold">Upload an Image</label>
<br>
<div id="direct_upload"
ngf-drop="uploadFiles($files)"
ngf-drag-over-class="dragOverClass($event)"
ng-model="files"
ng-multiple="true">
<form>
<div class="form_line">
<div class="form_controls">
<div class="upload_button_holder">
<div href="#" class="button" style="width:150px;" ngf-select="uploadFiles($files)" multiple title="upload" resetOnClick="true" >Upload</div>
</div>
</div>
<br>
</div>
</form>
</div>
<br>
</div>
home.s - 合适的控制器
app.controller('homeController', ['$scope','$http', 'Upload', 'cloudinary', function ($scope, $http, $upload, cloudinary) {
var cloud_name = "your cloud name";
var api_key = "your api_key";
var public_id = "your public_id";
var signature = "your signature";
var timestamp = "your timestamp";
$scope.uploadFiles = function(files){
if(!files){
return false;
}
angular.forEach(files, function(file){
if (file && !file.$error) {
file.upload = $upload.upload({
url: "https://api.cloudinary.com/v1_1/" + cloud_name + "/upload",
data: {
timestamp: timestamp,
public_id: public_id,
api_key: api_key,
signature: signature,
file: file
}
}).progress(function (e) {
file.progress = Math.round((e.loaded * 100.0) / e.total);
file.status = "Uploading... " + file.progress + "%";
}).success(function (data) {
console.log('success');
console.log(data);
alert('success');
}).error(function (data) {
console.log('failed');
console.log(data);
alert('failed');
});
}
});
};
}]);
希望这对您有所帮助:)
让我们花点时间指出 Cloudinary 的文档有多么糟糕。这很容易是我见过的最糟糕的。噩梦燃料。
现在我已经把它说出来了......我真的需要能够做到这一点,我绝对不想安装他们庞大的图书馆来做这件事,我也不想与JQuery(笑)。我花了太长时间用头撞墙,因为应该非常简单 - 但是 - 这是...
服务器(Node.js)
您需要一个端点,returns 到前端的签名-时间戳对:
import cloudinary from 'cloudinary'
export async function createImageUpload() {
const timestamp = new Date().getTime()
const signature = await cloudinary.utils.api_sign_request(
{
timestamp,
},
process.env.CLOUDINARY_SECRET
)
return { timestamp, signature }
}
客户端(浏览器)
客户端向服务器请求签名-时间戳对,然后使用它来上传文件。示例中使用的文件应来自 <input type='file'/>
更改事件等
const CLOUD_NAME = process.env.CLOUDINARY_CLOUD_NAME
const API_KEY = process.env.CLOUDINARY_API_KEY
async function uploadImage(file) {
const { signature, timestamp } = await api.post('/image-upload')
const form = new FormData()
form.append('file', file)
const res = await fetch(
`https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload?api_key=${API_KEY}×tamp=${timestamp}&signature=${signature}`,
{
method: 'POST',
body: form,
}
)
const data = await res.json()
return data.secure_url
}
就是这样。仅此而已。如果 Cloudinary 在他们的文档中有这个就好了。
我在没有 jQuery 的情况下使用 Cloudinary,并尝试通过浏览器直接上传。
我已按照说明 HERE 创建了一个名为 seller
的上传预设。
问题是,当我从客户端发帖时(使用 Angular),我得到回复:
XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/mycloud/image/upload. Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.
据我所知,这是一个 CORS 问题。我正在提出请求,如下所示。
req =
method: 'POST'
url: 'https://api.cloudinary.com/v1_1/mycloud/image/upload'
headers:
'Access-Control-Allow-Credentials': 'true'
file: scope.file
data:
upload_preset: 'seller'
$http(req)
.success (data, status, headers, config) ->
console.log 'file is uploaded successfully. Response: ' + data
.error (err) ->
console.log 'file error', err
我错过了什么?没有他们的 jQuery 插件就无法直接上传 Cloudinary 吗?
要解决许多 CORS 相关问题和浏览器不兼容问题,您最好使用来自 jquery.cloudinary.js 或 ng-file-upload 的基于 jQuery 的上传器。您可以在此处查看这两个示例 - https://github.com/cloudinary/cloudinary_angular/tree/master/samples/photo_album
特别是,CORS 请求因您传递的 Access-Control-Allow-Credentials header 而被拒绝。请尝试将其删除。
这是一个使用 AngularJS 1.3 的工作解决方案,可以在没有 jQuery 插件的情况下在 cloudinary 上执行直接未签名的上传:
var file = /* your file */;
var cloud_name = 'your cloud_name';
var fd = new FormData();
fd.append('upload_preset', 'seller');
fd.append('file', file);
$http
.post('https://api.cloudinary.com/v1_1/' + cloud_name + '/image/upload', fd, {
headers: {
'Content-Type': undefined,
'X-Requested-With': 'XMLHttpRequest'
}
})
.success(function (cloudinaryResponse) {
// do stuff with cloudinary response
// cloudinaryResponse = { public_id: ..., etc. }
})
.error(function (reponse) {
});
如果有人正在寻找 Angular ng-flow + cloudinary 解决方案,我在这里创建了一个基本设置
按照本教程进行简单的解决,效果很好..
http://prasanthco.de/tutorials/cloudinary-image-upload-using-angularjs/
这样做。
Index.html - 以相同顺序包含文件..
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.1/lodash.min.js"></script>
<script src="https://github.com/cloudinary/pkg-cloudinary-core/blob/master/cloudinary-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular.min.js"></script>
<script src="https://github.com/cloudinary/cloudinary_angular/blob/master/js/angular.cloudinary.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload.min.js"></script>
app.js - 注入模块
var app = angular.module('myApp', [
'cloudinary',
'ngFileUpload'
]);
home.html - 您需要图片上传选项的任何视图
<div class="container" ng-hide="loader">
<div class="deal">
<label class="black bold">Upload an Image</label>
<br>
<div id="direct_upload"
ngf-drop="uploadFiles($files)"
ngf-drag-over-class="dragOverClass($event)"
ng-model="files"
ng-multiple="true">
<form>
<div class="form_line">
<div class="form_controls">
<div class="upload_button_holder">
<div href="#" class="button" style="width:150px;" ngf-select="uploadFiles($files)" multiple title="upload" resetOnClick="true" >Upload</div>
</div>
</div>
<br>
</div>
</form>
</div>
<br>
</div>
home.s - 合适的控制器
app.controller('homeController', ['$scope','$http', 'Upload', 'cloudinary', function ($scope, $http, $upload, cloudinary) {
var cloud_name = "your cloud name";
var api_key = "your api_key";
var public_id = "your public_id";
var signature = "your signature";
var timestamp = "your timestamp";
$scope.uploadFiles = function(files){
if(!files){
return false;
}
angular.forEach(files, function(file){
if (file && !file.$error) {
file.upload = $upload.upload({
url: "https://api.cloudinary.com/v1_1/" + cloud_name + "/upload",
data: {
timestamp: timestamp,
public_id: public_id,
api_key: api_key,
signature: signature,
file: file
}
}).progress(function (e) {
file.progress = Math.round((e.loaded * 100.0) / e.total);
file.status = "Uploading... " + file.progress + "%";
}).success(function (data) {
console.log('success');
console.log(data);
alert('success');
}).error(function (data) {
console.log('failed');
console.log(data);
alert('failed');
});
}
});
};
}]);
希望这对您有所帮助:)
让我们花点时间指出 Cloudinary 的文档有多么糟糕。这很容易是我见过的最糟糕的。噩梦燃料。
现在我已经把它说出来了......我真的需要能够做到这一点,我绝对不想安装他们庞大的图书馆来做这件事,我也不想与JQuery(笑)。我花了太长时间用头撞墙,因为应该非常简单 - 但是 - 这是...
服务器(Node.js)
您需要一个端点,returns 到前端的签名-时间戳对:
import cloudinary from 'cloudinary'
export async function createImageUpload() {
const timestamp = new Date().getTime()
const signature = await cloudinary.utils.api_sign_request(
{
timestamp,
},
process.env.CLOUDINARY_SECRET
)
return { timestamp, signature }
}
客户端(浏览器)
客户端向服务器请求签名-时间戳对,然后使用它来上传文件。示例中使用的文件应来自 <input type='file'/>
更改事件等
const CLOUD_NAME = process.env.CLOUDINARY_CLOUD_NAME
const API_KEY = process.env.CLOUDINARY_API_KEY
async function uploadImage(file) {
const { signature, timestamp } = await api.post('/image-upload')
const form = new FormData()
form.append('file', file)
const res = await fetch(
`https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload?api_key=${API_KEY}×tamp=${timestamp}&signature=${signature}`,
{
method: 'POST',
body: form,
}
)
const data = await res.json()
return data.secure_url
}
就是这样。仅此而已。如果 Cloudinary 在他们的文档中有这个就好了。