是不是在跨域情况下 POST 时必须设置 x-www-form-urlencoded ?

我在使用 axios 进行跨域 POST 请求时,需要设置 Content-Type:application/x-www-form-urlencoded 才能正确发送数据( 不能使用默认的 application/application/json )。而使用 GET,或不跨域使用 POST 时都没有这个问题。

那么是不是在跨域情况下发送 POST 请求时,必须设置 Content-Type:application/x-www-form-urlencoded 呢?如果不是必须的话,在后端代码或服务器配置中要怎么做才能成功发送呢?

后台使用的是 PHP 框架 Laravel,已经加上了跨域相关的头:

$origin = $_SERVER['HTTP_ORIGIN'];
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Headers', 'Content-Type, content-type, X-Requested-With');
$response->header('Access-Control-Allow-Credentials', 'true');
$response->header('Access-Control-Allow-Methods', 'POST, PUT, DELETE, OPTIONS');
阅读 5.7k
3 个回答

通过查询资料,Laravel对于OPTIONS请求会自动常规响应200。所以缺少必要的头部信息。所以,我通过在路由中专门加入一个处理options的路由

引用自:http://www.bcty365.com/conten...

也就是说,我们需要在 laravel 中单独为 options 类请求加上处理:

Route::options('{any}', function ($any) {
    return response('ok');
})->middleware('cors');

注意,这里的路由路径需要和实际的 API 请求相同或覆盖之。CORS 中间件的内容为:

    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $origin = $_SERVER['HTTP_ORIGIN'];
        $response->header('Access-Control-Allow-Origin', $origin);
        $response->header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With');
        $response->header('Access-Control-Allow-Credentials', 'true');
        $response->header('Access-Control-Allow-Methods', 'POST, PUT, DELETE, OPTIONS');
        return $response;
    }

不是啊

可能是你的后台设置有问题,应该你的后台只设置了Content-Type为application/x-www-form-urlencoded的数据处理方式,Content-Type不一样,发送的数据格式也不一样,后台的处理方式也是不一样的

axios默认的Content-Type应该是application/json吧,你这里按照我上面的解析应该是发送出去了,只是后台没有办法处理

推荐后台看下这个教程后端接口支持跨域CORS调用


其中,

SpringMVC 3 支持跨域

SpringMVC 3不支持以上方法,通过Filter的方式实现。

这一点后台可以有如下设置

@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        /*
            需要根据请求头添加的header的字段来进行个性化配置
            如:Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With
        */
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}
    public void destroy() {}
}

web.xml里配置

<filter>
    <filter-name>cors</filter-name>
    <filter-class>test.cors.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在这种设置下 前端不用有任何操作,就可以实现跨域请求,其实重点就是服务器要支持跨域请求,以上我是以fetch请求做的测试,
如果需要在请求的时候携带cookie,参考以下两种方式

var xhr = new XMLHttpRequest();
// 自动发送cookies
xhr.withCredentials = true;
fetch(url, {
credentials:"include",// 自动发送cookies
method: method,
headers: header,
mode: "cors"
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题