天天看点

OSS 跨域配置

作者:张医博

什么是 “跨域”

一句话简单说明

一个资源请求一个其它域名的资源时会发起一个跨域 HTTP 请求 (cross-origin HTTP request)。比如说,域名 A

http://domaina.example

的某 Web 应用通过

<img>

标签引入了域名

B:

http://domainb.foo

的某图片资源

http://domainb.foo/image.jpg

,域名 A 的 Web 应用会触发浏览器发起一个跨域 HTTP 请求。

demo

http://www. class="hljs-number">123.com/index.html 调用            http://www. class="hljs-number">123.com/server.php (非跨域)               
http://www. http://www. http://www. http://www. http://www. http://www. http://www. http://www.

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

http://www.

跨域请求标识

origin ,当浏览器识别出 client 发起的请求需要转到另外一个域名上处理是,会在请求的 request header 中增加一个 origin 标识,如下我用 curl 测试了一个域名。

curl -voa         http: class="hljs-comment">//mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/010/personal.jpg -H "Origin:www.mobby.cn"       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current               
Dload  Upload   Total   Spent    Left  Speed                    

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 59.110.190.173...

TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com (59.110.190.173) port 80 (#0)

> GET /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

>

< HTTP/1.1 200 OK

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 12:30:28 GMT

< Content-Type: image/jpeg

< Content-Length: 8407

< Connection: keep-alive

< x-oss-request-id:

< Access-Control-Allow-Origin: www.mobby.cn

< Access-Control-Allow-Credentials: true

< Access-Control-Allow-Methods: GET, POST, HEAD

< Access-Control-Max-Age: 0

< Accept-Ranges: bytes

可以看到挡我发起 Origin 的请求头后,如果目标的网页服务允许来源的域名访问,就会在响应的 Response header 中带上跨域的响应头。(以下 header 目标域名如果设置了才会有响应)

< Access-Control-Allow-Origin: www.mobby.cn (允许的跨域来源,可以写 *,或者绝对域名) 
< Access-Control-Allow-Headers: *(允许跨域时携带哪些 header )
< Access-Control-Allow-Methods: GET, POST, HEAD (允许哪些跨域请求方法,origin 是默认支持的)           

常见案例分析

场景 一:CDN 访问 CDN 跨域被拦截

OSS 跨域配置

通过报错可以看出来 发起跨区域请求的源头 是 bo3.ai.com 加载了 www.ai.com 网站的资源,这两个域名都在 阿里云 cdn 加速。既然找到了请求目的 www.ai.com,那么直接检查下目的域名上是否新增了跨域头。这种情况基本都是目的域名没有加上允许的跨域头导致。

场景二:直传 OSS 引用 CDN 资源被拦截

OSS 跨域配置

用户直接上传到 OSS ,但是应用了 CDN 的域名时出现的跨域的报错,出现这种情况因为引用的 CDN 上没有配置跨域的属性所以报错,在 CDN 上配置好跨域参数后问题解决。

找到阿里 CDN 控制台对应的 CDN 域名,配置 http header 头,增加三个属性,如下:

OSS 跨域配置

场景三:CDN 回源到 OSS

OSS 跨域配置

这个问题比较特殊,拆分两部分说明;

出现这种情况,通过截图我们发现用户有两种请求,分别是

GET

POST

两种,由于

GET

好测试,我们先说

GET

GET:

出现跨域错误,首先就要检查原是否添加了跨域头,于是我们使用 curl 测试一下,如果最简单的 get 测试成功返回跨域头,说明目的 域名设置了跨域响应,如果测试失败说明原没有添加跨域响应。通过如下图很显然看到了目的添加了跨域头。

curl -voa         http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/ class="hljs-number">010/personal.jpg -H "Origin:www.mo.cn"       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current               
Dload  Upload   Total   Spent    Left  Speed                    
http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 59.110.190.173...

http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com () port 80 (#0)

> GET /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

>

< HTTP/1.1 200 OK

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 12:30:28 GMT

< Content-Type: image/jpeg

< Content-Length: 8407

< Connection: keep-alive

< x-oss-request-id: 5B951264980F8FDB749972B3

< Access-Control-Allow-Origin: www.mo.cn

< Access-Control-Allow-Credentials: true

< Access-Control-Allow-Methods: GET, POST, HEAD

< Access-Control-Max-Age: 0

http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

POST

通过

GET

测试发现 oss 是加了跨域头的,但是为什么

POST

请求就返回 405 呢?没有任何跨域头呢?用户反馈为什么手动 curl 测试也是失败。

curl -v -X POST -d '{"user":"xxx"}'         http: class="hljs-comment">//mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/010/personal.jpg -H "Origin:www.mo.cn"     Note: Unnecessary use of -X or --request, POST is already inferred.               

Trying 59.110.190.173...TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com (59.110.190.173) port 80 (#0)

> POST /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

> Content-Length: 14

> Content-Type: application/x-www-form-urlencoded

>

upload completely sent off: 14 out of 14 bytes

< HTTP/1.1 405 Method Not Allowed

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 13:06:28 GMT

< Content-Type: application/xml

< Content-Length: 337

< Connection: keep-alive

< x-oss-request-id:

< Allow: GET DELETE HEAD PUT POST OPTIONS

<

<?xml version="1.0" encoding="UTF-8"?>

<Error>

<Code>MethodNotAllowed</Code>

<Message>The specified method is not allowed against this resource.</Message>

<RequestId></RequestId>

<HostId>mo-im.oss-cn-beijing.aliyuncs.com</HostId>

<Method>POST</Method>

<ResourceType>Object</ResourceType>

</Error>

结论:

  • 请求的格式不是 RFC 标准规定的 content-type:multipart/form-data;
  • 请求头不是内容不是 RFC 规定的表单域提交;
  • 既然不是表单域,那么 OSS API 要求的 filename 参数肯定也不是放在最后一个选项。

JAVA 跨域请求源码

package com.alibaba.edas.carshop.OSS;           

import javax.activation.MimetypesFileTypeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry;

public class OSSPostFile {

<span class="hljs-comment">// The local file path to upload.</span>
<span class="hljs-keyword">private</span> String localFilePath = <span class="hljs-string">"C:\\T\\1.txt"</span>;
<span class="hljs-comment">// OSS domain, such as http://oss-cn-hangzhou.aliyuncs.com</span>
<span class="hljs-keyword">private</span> String endpoint = <span class="hljs-string">"http://oss-cn-beijing.aliyuncs.com"</span>;
<span class="hljs-comment">// Access key Id. Please get it from https://ak-console.aliyun.com</span>
<span class="hljs-keyword">private</span> String accessKeyId = <span class="hljs-string">""</span>;
<span class="hljs-keyword">private</span> String accessKeySecret = <span class="hljs-string">""</span>;
<span class="hljs-comment">// The existing bucket name</span>
<span class="hljs-keyword">private</span> String bucketName = <span class="hljs-string">"您自己的bucket名称"</span>;
<span class="hljs-comment">// The key name for the file to upload.</span>
<span class="hljs-keyword">private</span> String key = <span class="hljs-string">"1.txt"</span>;

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PostObject</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
    <span class="hljs-comment">// append the 'bucketname.' prior to the domain, such as</span>
    <span class="hljs-comment">// http://bucket1.oss-cn-hangzhou.aliyuncs.com.</span>
    String urlStr = endpoint.replace(<span class="hljs-string">"http://"</span>, <span class="hljs-string">"http://"</span> + bucketName + <span class="hljs-string">"."</span>);

    <span class="hljs-comment">// form fields</span>
    Map&lt;String, String&gt; formFields = <span class="hljs-keyword">new</span> LinkedHashMap&lt;String, String&gt;();

    <span class="hljs-comment">// key</span>
    formFields.put(<span class="hljs-string">"key"</span>, <span class="hljs-keyword">this</span>.key);
    <span class="hljs-comment">// Content-Disposition</span>
    formFields.put(<span class="hljs-string">"Content-Disposition"</span>, <span class="hljs-string">"attachment;filename="</span> + localFilePath);
    <span class="hljs-comment">// OSSAccessKeyId</span>
    formFields.put(<span class="hljs-string">"OSSAccessKeyId"</span>, accessKeyId);
    <span class="hljs-comment">// policy</span>
    String policy = <span class="hljs-string">"{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [[\"content-length-range\", 0, 104857600000]]}"</span>;
    String encodePolicy = <span class="hljs-keyword">new</span> String(Base64.encodeBase64(policy.getBytes()));
    formFields.put(<span class="hljs-string">"policy"</span>, encodePolicy);
    <span class="hljs-comment">// Signature</span>
    String signaturecom = computeSignature(accessKeySecret, encodePolicy);
    formFields.put(<span class="hljs-string">"Signature"</span>, signaturecom);

    String ret = formUpload(urlStr, formFields, localFilePath);

    System.out.println(<span class="hljs-string">"Post Object ["</span> + <span class="hljs-keyword">this</span>.key + <span class="hljs-string">"] to bucket ["</span> + bucketName + <span class="hljs-string">"]"</span>);
    System.out.println(<span class="hljs-string">"post reponse:"</span> + ret);
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">computeSignature</span><span class="hljs-params">(String accessKeySecret, String encodePolicy)</span>
        <span class="hljs-keyword">throws</span> UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException </span>{
    <span class="hljs-comment">// convert to UTF-8</span>
    <span class="hljs-keyword">byte</span>[] key = accessKeySecret.getBytes(<span class="hljs-string">"UTF-8"</span>);
    <span class="hljs-keyword">byte</span>[] data = encodePolicy.getBytes(<span class="hljs-string">"UTF-8"</span>);

    <span class="hljs-comment">// hmac-sha1</span>
    Mac mac = Mac.getInstance(<span class="hljs-string">"HmacSHA1"</span>);
    mac.init(<span class="hljs-keyword">new</span> SecretKeySpec(key, <span class="hljs-string">"HmacSHA1"</span>));
    <span class="hljs-keyword">byte</span>[] sha = mac.doFinal(data);

    <span class="hljs-comment">// base64</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> String(Base64.encodeBase64(sha));
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">formUpload</span><span class="hljs-params">(String urlStr, Map&lt;String, String&gt; formFields, String localFile)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    String res = <span class="hljs-string">""</span>;
    HttpURLConnection conn = <span class="hljs-keyword">null</span>;
    String boundary = <span class="hljs-string">"9431149156168"</span>;

    <span class="hljs-keyword">try</span> {
        URL url = <span class="hljs-keyword">new</span> URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(<span class="hljs-number">5000</span>);
        conn.setReadTimeout(<span class="hljs-number">30000</span>);
        conn.setDoOutput(<span class="hljs-keyword">true</span>);
        conn.setDoInput(<span class="hljs-keyword">true</span>);
        conn.setRequestMethod(<span class="hljs-string">"POST"</span>);
        conn.setRequestProperty(<span class="hljs-string">"User-Agent"</span>, <span class="hljs-string">"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"</span>);
        conn.setRequestProperty(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"multipart/form-data; boundary="</span> + boundary);
        OutputStream out = <span class="hljs-keyword">new</span> DataOutputStream(conn.getOutputStream());

        <span class="hljs-comment">// text</span>
        <span class="hljs-keyword">if</span> (formFields != <span class="hljs-keyword">null</span>) {
            StringBuffer strBuf = <span class="hljs-keyword">new</span> StringBuffer();
            Iterator&lt;Entry&lt;String, String&gt;&gt; iter = formFields.entrySet().iterator();
            <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;

            <span class="hljs-keyword">while</span> (iter.hasNext()) {
                Entry&lt;String, String&gt; entry = iter.next();
                String inputName = entry.getKey();
                String inputValue = entry.getValue();

                <span class="hljs-keyword">if</span> (inputValue == <span class="hljs-keyword">null</span>) {
                    <span class="hljs-keyword">continue</span>;
                }

                <span class="hljs-keyword">if</span> (i == <span class="hljs-number">0</span>) {
                    strBuf.append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
                    strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\""</span> + inputName + <span class="hljs-string">"\"\r\n\r\n"</span>);
                    strBuf.append(inputValue);
                } <span class="hljs-keyword">else</span> {
                    strBuf.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
                    strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\""</span> + inputName + <span class="hljs-string">"\"\r\n\r\n"</span>);
                    strBuf.append(inputValue);
                }

                i++;
            }
            out.write(strBuf.toString().getBytes());
        }

        StringBuffer strBuf1 = <span class="hljs-keyword">new</span> StringBuffer();
        String callback = <span class="hljs-string">"{\"callbackUrl\":\"http://47.93.116.168/Revice.ashx\",\"callbackBody\":\"{\\\"bucket\\\"=${bucket},\\\"size\\\"=${size}}\"}"</span>;

        <span class="hljs-keyword">byte</span>[] textByte = callback.getBytes(<span class="hljs-string">"UTF-8"</span>);
        strBuf1.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);

        String callbackstr = <span class="hljs-keyword">new</span> String(Base64.encodeBase64(textByte));
        strBuf1.append(<span class="hljs-string">"Content-Disposition: form-data; name=\"callback\"\r\n\r\n"</span> + callbackstr + <span class="hljs-string">"\r\n\r\n"</span>);
        out.write(strBuf1.toString().getBytes());

        <span class="hljs-comment">// file</span>
        File file = <span class="hljs-keyword">new</span> File(localFile);
        String filename = file.getName();
        String contentType = <span class="hljs-keyword">new</span> MimetypesFileTypeMap().getContentType(file);
        <span class="hljs-keyword">if</span> (contentType == <span class="hljs-keyword">null</span> || contentType.equals(<span class="hljs-string">""</span>)) {
            contentType = <span class="hljs-string">"application/octet-stream"</span>;
        }

        StringBuffer strBuf = <span class="hljs-keyword">new</span> StringBuffer();
        strBuf.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
        strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\"file\"; "</span> + <span class="hljs-string">"filename=\""</span> + filename + <span class="hljs-string">"\"\r\n"</span>);
        strBuf.append(<span class="hljs-string">"Content-Type: "</span> + contentType + <span class="hljs-string">"\r\n\r\n"</span>);
        out.write(strBuf.toString().getBytes());

        DataInputStream in = <span class="hljs-keyword">new</span> DataInputStream(<span class="hljs-keyword">new</span> FileInputStream(file));
        <span class="hljs-keyword">int</span> bytes = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">byte</span>[] bufferOut = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">1024</span>];
        <span class="hljs-keyword">while</span> ((bytes = in.read(bufferOut)) != -<span class="hljs-number">1</span>) {
            out.write(bufferOut, <span class="hljs-number">0</span>, bytes);
        }
        in.close();

        <span class="hljs-keyword">byte</span>[] endData = (<span class="hljs-string">"\r\n--"</span> + boundary + <span class="hljs-string">"--\r\n"</span>).getBytes();
        out.write(endData);
        out.flush();
        out.close();

        <span class="hljs-comment">// Gets the file data</span>
        strBuf = <span class="hljs-keyword">new</span> StringBuffer();
        BufferedReader reader = <span class="hljs-keyword">new</span> BufferedReader(<span class="hljs-keyword">new</span> InputStreamReader(conn.getInputStream()));
        String line = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">while</span> ((line = reader.readLine()) != <span class="hljs-keyword">null</span>) {
            strBuf.append(line).append(<span class="hljs-string">"\n"</span>);
        }
        res = strBuf.toString();
        reader.close();
        reader = <span class="hljs-keyword">null</span>;
    } <span class="hljs-keyword">catch</span> (Exception e) {
        System.err.println(<span class="hljs-string">"Send post request exception: "</span> + e.getLocalizedMessage());
        <span class="hljs-keyword">throw</span> e;
    } <span class="hljs-keyword">finally</span> {
        <span class="hljs-keyword">if</span> (conn != <span class="hljs-keyword">null</span>) {
            conn.disconnect();
            conn = <span class="hljs-keyword">null</span>;
        }
    }

    <span class="hljs-keyword">return</span> res;
}
                

}

测试结果

OSS 跨域配置

场景四:

OSS 控制台配置跨域规则失败

OSS 跨域配置

初步分析:出现的原因是因为用户之前历史配置过的规则中含有特殊字符导致控制台拉取是否有历史配置时失败,响应了 invalidresponse。

解决方法:用户通过 SDK 修改跨域规则,通过 SDK 配置的规则将历史规则覆盖掉。

场景五:客户端使用 cavens 测试图片的跨域访问被 403

OSS 跨域配置

1、先确认 OSS 是否非配置了跨域头,配置的是否正确;

OSS 跨域配置

2、出现类似问题可以使用 postman 或者 curl 工具测试,看下是否同样出现问题。

OSS 跨域配置

3、如果发现本地测试跨域头都是正常的,只有客户端的浏览器测试异常,请用户清除浏览器缓存,开启隐私模式进行测试。

http://domaina.example

<img>

B:

http://domainb.foo

http://domainb.foo/image.jpg

http://www. class="hljs-number">123.com/index.html 调用            http://www. class="hljs-number">123.com/server.php (非跨域)               
http://www. http://www. http://www. http://www. http://www. http://www. http://www. http://www.

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

http://www.

curl -voa         http: class="hljs-comment">//mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/010/personal.jpg -H "Origin:www.mobby.cn"       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current               
Dload  Upload   Total   Spent    Left  Speed                    

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 59.110.190.173...

TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com (59.110.190.173) port 80 (#0)

> GET /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

>

< HTTP/1.1 200 OK

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 12:30:28 GMT

< Content-Type: image/jpeg

< Content-Length: 8407

< Connection: keep-alive

< x-oss-request-id:

< Access-Control-Allow-Origin: www.mobby.cn

< Access-Control-Allow-Credentials: true

< Access-Control-Allow-Methods: GET, POST, HEAD

< Access-Control-Max-Age: 0

< Accept-Ranges: bytes

< Access-Control-Allow-Origin: www.mobby.cn (允许的跨域来源,可以写 *,或者绝对域名) 
< Access-Control-Allow-Headers: *(允许跨域时携带哪些 header )
< Access-Control-Allow-Methods: GET, POST, HEAD (允许哪些跨域请求方法,origin 是默认支持的)           

OSS 跨域配置

OSS 跨域配置
OSS 跨域配置

OSS 跨域配置

GET

POST

GET

GET

curl -voa         http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/ class="hljs-number">010/personal.jpg -H "Origin:www.mo.cn"       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current               
Dload  Upload   Total   Spent    Left  Speed                    
http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 59.110.190.173...

http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com () port 80 (#0)

> GET /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

>

< HTTP/1.1 200 OK

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 12:30:28 GMT

< Content-Type: image/jpeg

< Content-Length: 8407

< Connection: keep-alive

< x-oss-request-id: 5B951264980F8FDB749972B3

< Access-Control-Allow-Origin: www.mo.cn

< Access-Control-Allow-Credentials: true

< Access-Control-Allow-Methods: GET, POST, HEAD

< Access-Control-Max-Age: 0

http://mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/

GET

POST

curl -v -X POST -d '{"user":"xxx"}'         http: class="hljs-comment">//mo-im.oss-cn-beijing.aliyuncs.com/stu_avatar/010/personal.jpg -H "Origin:www.mo.cn"     Note: Unnecessary use of -X or --request, POST is already inferred.               

Trying 59.110.190.173...TCP_NODELAY setConnected to mo-im.oss-cn-beijing.aliyuncs.com (59.110.190.173) port 80 (#0)

> POST /stu_avatar/010/personal.jpg HTTP/1.1

> Host: mo-im.oss-cn-beijing.aliyuncs.com

> User-Agent: curl/7.54.0

> Accept: /

> Origin:www.mo.cn

> Content-Length: 14

> Content-Type: application/x-www-form-urlencoded

>

upload completely sent off: 14 out of 14 bytes

< HTTP/1.1 405 Method Not Allowed

< Server: AliyunOSS

< Date: Sun, 09 Sep 2018 13:06:28 GMT

< Content-Type: application/xml

< Content-Length: 337

< Connection: keep-alive

< x-oss-request-id:

< Allow: GET DELETE HEAD PUT POST OPTIONS

<

<?xml version="1.0" encoding="UTF-8"?>

<Error>

<Code>MethodNotAllowed</Code>

<Message>The specified method is not allowed against this resource.</Message>

<RequestId></RequestId>

<HostId>mo-im.oss-cn-beijing.aliyuncs.com</HostId>

<Method>POST</Method>

<ResourceType>Object</ResourceType>

</Error>

结论:

package com.alibaba.edas.carshop.OSS;           

import javax.activation.MimetypesFileTypeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry;

public class OSSPostFile {

<span class="hljs-comment">// The local file path to upload.</span>
<span class="hljs-keyword">private</span> String localFilePath = <span class="hljs-string">"C:\\T\\1.txt"</span>;
<span class="hljs-comment">// OSS domain, such as http://oss-cn-hangzhou.aliyuncs.com</span>
<span class="hljs-keyword">private</span> String endpoint = <span class="hljs-string">"http://oss-cn-beijing.aliyuncs.com"</span>;
<span class="hljs-comment">// Access key Id. Please get it from https://ak-console.aliyun.com</span>
<span class="hljs-keyword">private</span> String accessKeyId = <span class="hljs-string">""</span>;
<span class="hljs-keyword">private</span> String accessKeySecret = <span class="hljs-string">""</span>;
<span class="hljs-comment">// The existing bucket name</span>
<span class="hljs-keyword">private</span> String bucketName = <span class="hljs-string">"您自己的bucket名称"</span>;
<span class="hljs-comment">// The key name for the file to upload.</span>
<span class="hljs-keyword">private</span> String key = <span class="hljs-string">"1.txt"</span>;

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PostObject</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
    <span class="hljs-comment">// append the 'bucketname.' prior to the domain, such as</span>
    <span class="hljs-comment">// http://bucket1.oss-cn-hangzhou.aliyuncs.com.</span>
    String urlStr = endpoint.replace(<span class="hljs-string">"http://"</span>, <span class="hljs-string">"http://"</span> + bucketName + <span class="hljs-string">"."</span>);

    <span class="hljs-comment">// form fields</span>
    Map&lt;String, String&gt; formFields = <span class="hljs-keyword">new</span> LinkedHashMap&lt;String, String&gt;();

    <span class="hljs-comment">// key</span>
    formFields.put(<span class="hljs-string">"key"</span>, <span class="hljs-keyword">this</span>.key);
    <span class="hljs-comment">// Content-Disposition</span>
    formFields.put(<span class="hljs-string">"Content-Disposition"</span>, <span class="hljs-string">"attachment;filename="</span> + localFilePath);
    <span class="hljs-comment">// OSSAccessKeyId</span>
    formFields.put(<span class="hljs-string">"OSSAccessKeyId"</span>, accessKeyId);
    <span class="hljs-comment">// policy</span>
    String policy = <span class="hljs-string">"{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [[\"content-length-range\", 0, 104857600000]]}"</span>;
    String encodePolicy = <span class="hljs-keyword">new</span> String(Base64.encodeBase64(policy.getBytes()));
    formFields.put(<span class="hljs-string">"policy"</span>, encodePolicy);
    <span class="hljs-comment">// Signature</span>
    String signaturecom = computeSignature(accessKeySecret, encodePolicy);
    formFields.put(<span class="hljs-string">"Signature"</span>, signaturecom);

    String ret = formUpload(urlStr, formFields, localFilePath);

    System.out.println(<span class="hljs-string">"Post Object ["</span> + <span class="hljs-keyword">this</span>.key + <span class="hljs-string">"] to bucket ["</span> + bucketName + <span class="hljs-string">"]"</span>);
    System.out.println(<span class="hljs-string">"post reponse:"</span> + ret);
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">computeSignature</span><span class="hljs-params">(String accessKeySecret, String encodePolicy)</span>
        <span class="hljs-keyword">throws</span> UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException </span>{
    <span class="hljs-comment">// convert to UTF-8</span>
    <span class="hljs-keyword">byte</span>[] key = accessKeySecret.getBytes(<span class="hljs-string">"UTF-8"</span>);
    <span class="hljs-keyword">byte</span>[] data = encodePolicy.getBytes(<span class="hljs-string">"UTF-8"</span>);

    <span class="hljs-comment">// hmac-sha1</span>
    Mac mac = Mac.getInstance(<span class="hljs-string">"HmacSHA1"</span>);
    mac.init(<span class="hljs-keyword">new</span> SecretKeySpec(key, <span class="hljs-string">"HmacSHA1"</span>));
    <span class="hljs-keyword">byte</span>[] sha = mac.doFinal(data);

    <span class="hljs-comment">// base64</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> String(Base64.encodeBase64(sha));
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">formUpload</span><span class="hljs-params">(String urlStr, Map&lt;String, String&gt; formFields, String localFile)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    String res = <span class="hljs-string">""</span>;
    HttpURLConnection conn = <span class="hljs-keyword">null</span>;
    String boundary = <span class="hljs-string">"9431149156168"</span>;

    <span class="hljs-keyword">try</span> {
        URL url = <span class="hljs-keyword">new</span> URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(<span class="hljs-number">5000</span>);
        conn.setReadTimeout(<span class="hljs-number">30000</span>);
        conn.setDoOutput(<span class="hljs-keyword">true</span>);
        conn.setDoInput(<span class="hljs-keyword">true</span>);
        conn.setRequestMethod(<span class="hljs-string">"POST"</span>);
        conn.setRequestProperty(<span class="hljs-string">"User-Agent"</span>, <span class="hljs-string">"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"</span>);
        conn.setRequestProperty(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"multipart/form-data; boundary="</span> + boundary);
        OutputStream out = <span class="hljs-keyword">new</span> DataOutputStream(conn.getOutputStream());

        <span class="hljs-comment">// text</span>
        <span class="hljs-keyword">if</span> (formFields != <span class="hljs-keyword">null</span>) {
            StringBuffer strBuf = <span class="hljs-keyword">new</span> StringBuffer();
            Iterator&lt;Entry&lt;String, String&gt;&gt; iter = formFields.entrySet().iterator();
            <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;

            <span class="hljs-keyword">while</span> (iter.hasNext()) {
                Entry&lt;String, String&gt; entry = iter.next();
                String inputName = entry.getKey();
                String inputValue = entry.getValue();

                <span class="hljs-keyword">if</span> (inputValue == <span class="hljs-keyword">null</span>) {
                    <span class="hljs-keyword">continue</span>;
                }

                <span class="hljs-keyword">if</span> (i == <span class="hljs-number">0</span>) {
                    strBuf.append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
                    strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\""</span> + inputName + <span class="hljs-string">"\"\r\n\r\n"</span>);
                    strBuf.append(inputValue);
                } <span class="hljs-keyword">else</span> {
                    strBuf.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
                    strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\""</span> + inputName + <span class="hljs-string">"\"\r\n\r\n"</span>);
                    strBuf.append(inputValue);
                }

                i++;
            }
            out.write(strBuf.toString().getBytes());
        }

        StringBuffer strBuf1 = <span class="hljs-keyword">new</span> StringBuffer();
        String callback = <span class="hljs-string">"{\"callbackUrl\":\"http://47.93.116.168/Revice.ashx\",\"callbackBody\":\"{\\\"bucket\\\"=${bucket},\\\"size\\\"=${size}}\"}"</span>;

        <span class="hljs-keyword">byte</span>[] textByte = callback.getBytes(<span class="hljs-string">"UTF-8"</span>);
        strBuf1.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);

        String callbackstr = <span class="hljs-keyword">new</span> String(Base64.encodeBase64(textByte));
        strBuf1.append(<span class="hljs-string">"Content-Disposition: form-data; name=\"callback\"\r\n\r\n"</span> + callbackstr + <span class="hljs-string">"\r\n\r\n"</span>);
        out.write(strBuf1.toString().getBytes());

        <span class="hljs-comment">// file</span>
        File file = <span class="hljs-keyword">new</span> File(localFile);
        String filename = file.getName();
        String contentType = <span class="hljs-keyword">new</span> MimetypesFileTypeMap().getContentType(file);
        <span class="hljs-keyword">if</span> (contentType == <span class="hljs-keyword">null</span> || contentType.equals(<span class="hljs-string">""</span>)) {
            contentType = <span class="hljs-string">"application/octet-stream"</span>;
        }

        StringBuffer strBuf = <span class="hljs-keyword">new</span> StringBuffer();
        strBuf.append(<span class="hljs-string">"\r\n"</span>).append(<span class="hljs-string">"--"</span>).append(boundary).append(<span class="hljs-string">"\r\n"</span>);
        strBuf.append(<span class="hljs-string">"Content-Disposition: form-data; name=\"file\"; "</span> + <span class="hljs-string">"filename=\""</span> + filename + <span class="hljs-string">"\"\r\n"</span>);
        strBuf.append(<span class="hljs-string">"Content-Type: "</span> + contentType + <span class="hljs-string">"\r\n\r\n"</span>);
        out.write(strBuf.toString().getBytes());

        DataInputStream in = <span class="hljs-keyword">new</span> DataInputStream(<span class="hljs-keyword">new</span> FileInputStream(file));
        <span class="hljs-keyword">int</span> bytes = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">byte</span>[] bufferOut = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">1024</span>];
        <span class="hljs-keyword">while</span> ((bytes = in.read(bufferOut)) != -<span class="hljs-number">1</span>) {
            out.write(bufferOut, <span class="hljs-number">0</span>, bytes);
        }
        in.close();

        <span class="hljs-keyword">byte</span>[] endData = (<span class="hljs-string">"\r\n--"</span> + boundary + <span class="hljs-string">"--\r\n"</span>).getBytes();
        out.write(endData);
        out.flush();
        out.close();

        <span class="hljs-comment">// Gets the file data</span>
        strBuf = <span class="hljs-keyword">new</span> StringBuffer();
        BufferedReader reader = <span class="hljs-keyword">new</span> BufferedReader(<span class="hljs-keyword">new</span> InputStreamReader(conn.getInputStream()));
        String line = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">while</span> ((line = reader.readLine()) != <span class="hljs-keyword">null</span>) {
            strBuf.append(line).append(<span class="hljs-string">"\n"</span>);
        }
        res = strBuf.toString();
        reader.close();
        reader = <span class="hljs-keyword">null</span>;
    } <span class="hljs-keyword">catch</span> (Exception e) {
        System.err.println(<span class="hljs-string">"Send post request exception: "</span> + e.getLocalizedMessage());
        <span class="hljs-keyword">throw</span> e;
    } <span class="hljs-keyword">finally</span> {
        <span class="hljs-keyword">if</span> (conn != <span class="hljs-keyword">null</span>) {
            conn.disconnect();
            conn = <span class="hljs-keyword">null</span>;
        }
    }

    <span class="hljs-keyword">return</span> res;
}
                

}

OSS 跨域配置

OSS 跨域配置

OSS 跨域配置
OSS 跨域配置
OSS 跨域配置